ios UIRefreshControl - 释放触摸后如何进行刷新操作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15584104/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UIRefreshControl - How do I make the refresh action occur after the touch is released?
提问by outphase
Long time listener, first time caller here on stack overflow. Be gentle.
长时间的监听器,堆栈溢出时的第一次调用者。要温柔。
I am implementing UIRefreshControl on a UITableView to refresh the table's data. On other pull-to-refresh implementations, the refresh process does not begin until the user's finger is lifted while in the pull's refresh distance. UIRefreshControl does not immediately seem like it has this customization.
我正在 UITableView 上实现 UIRefreshControl 以刷新表的数据。在其他下拉刷新实现中,刷新过程直到用户的手指在下拉刷新距离内被抬起时才开始。UIRefreshControl 似乎并没有立即进行此自定义。
My UIRefreshControl init code:
我的 UIRefreshControl 初始化代码:
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];
[self.tableView addSubview:refreshControl];
My refresh: code is fairly basic:
我的刷新:代码相当基本:
-(void)refresh:(id)sender {
(... refresh code ...)
[sender endRefreshing];
}
How can I delay the refresh: function until the user removes their finger from the pull?
如何延迟 refresh: 功能,直到用户将手指从拉动中移开?
回答by Ned
I've also stuck with the same problem. I don't think that my approach is very nice, but seems like it works.
我也遇到了同样的问题。我不认为我的方法很好,但似乎有效。
Init
UIRefreshControl
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; self.refreshControl = refreshControl;
Check state of
UIRefreshControl
when user finish dragging the table (UITableViewDelegate
conforms toUIScrollViewDelegate
)- (void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView { if( self.refreshControl.isRefreshing ) [self refresh]; }
Update table
- (void)refresh { [self.refreshControl endRefreshing]; // TODO: Update here your items [self.tableView reloadData]; }
在里面
UIRefreshControl
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; self.refreshControl = refreshControl;
检查
UIRefreshControl
用户完成拖动表格时的状态(UITableViewDelegate
符合UIScrollViewDelegate
)- (void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView { if( self.refreshControl.isRefreshing ) [self refresh]; }
更新表
- (void)refresh { [self.refreshControl endRefreshing]; // TODO: Update here your items [self.tableView reloadData]; }
Hope it will help you.
希望它会帮助你。
回答by outphase
UIRefreshControl
already has accommodations for starting at the "right" time. The correct behavior for a pull-to-refresh control is to start the refresh after the user has crossed some "far enough" threshold, not when the user has released their drag.
UIRefreshControl
已经有了在“正确”时间开始的住宿。下拉刷新控件的正确行为是在用户超过某个“足够远”的阈值后开始刷新,而不是在用户释放拖动时开始刷新。
In order to accomplish this, you need to modify your -refresh:
method to check for when the control has transitioned into the refreshing
state:
为了实现这一点,您需要修改您的-refresh:
方法以检查控件何时转换为refreshing
状态:
-(void)refresh:(id)sender {
UIRefreshControl *refreshControl = (UIRefreshControl *)sender;
if(refreshControl.refreshing) {
(... refresh code ...)
}
}
Note that any method you call for your (... refresh code ...)
should be asynchronous, so that your UI doesn't freeze. You should change to main queue and call -endRefreshing
at the end of your (... refresh code ...)
block, instead of at the end of -refresh:
:
请注意,您调用的任何方法都(... refresh code ...)
应该是异步的,这样您的 UI 就不会冻结。您应该更改到主队列并-endRefreshing
在(... refresh code ...)
块的末尾调用,而不是在-refresh:
:
- (void)refresh:(id)sender {
__weak UIRefreshControl *refreshControl = (UIRefreshControl *)sender;
if(refreshControl.refreshing) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
/* (... refresh code ...) */
dispatch_sync(dispatch_get_main_queue(), ^{
[refreshControl endRefreshing];
//reload the table here, too
});
});
}
}
Changing the control event to UIControlEventTouchUpInside
will not work because UIRefreshControl
is not a UI component intended to be directly interacted with. The user will never touchthe UIRefreshControl
, so no UIControlEventTouchUpInside
event can be triggered.
将控件事件更改为UIControlEventTouchUpInside
将不起作用,因为UIRefreshControl
它不是旨在直接与之交互的 UI 组件。用户永远不会碰的UIRefreshControl
,所以没有UIControlEventTouchUpInside
事件可以触发。
回答by DrMickeyLauer
Scheduling the refresh to only occur when the finger has lifted can be achieved by using NSRunLoop
. Call -(void)performInModes:(NSArray<NSRunLoopMode> *)modes block:(void (^)(void))block;
with NSRunLoopDefaultMode
in the array.
可以使用NSRunLoop
. 在数组中调用-(void)performInModes:(NSArray<NSRunLoopMode> *)modes block:(void (^)(void))block;
with NSRunLoopDefaultMode
。
While the touch is still held, the runloop mode is UITrackingRunLoopMode
, it will only go back to the default after liftoff.
当触摸仍然保持时,运行循环模式是UITrackingRunLoopMode
,它只会在升空后恢复到默认值。