长时间监听,第一次调用堆栈溢出。要温柔。
我在UITableView上实现UIRefreshControl来刷新表的数据。在其他拉动刷新实现中,刷新过程不会开始,直到用户的手指在拉动刷新距离内被抬起。 UIRefreshControl似乎没有立即显示它。
我的UIRefreshControl初始化代码:
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];
[self.tableView addSubview:refreshControl];
我的刷新:代码非常基础:
-(void)refresh:(id)sender {
(... refresh code ...)
[sender endRefreshing];
}
如何延迟刷新:功能,直到用户从拉动中移开手指?
答案 0 :(得分:37)
我也遇到了同样的问题。我不认为我的方法很好,但看起来很有效。
初始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];
}
希望它会对你有所帮助。
答案 1 :(得分:20)
UIRefreshControl
已经有了在“正确”时间开始的住宿。 pull-to-refresh控件的正确行为是在用户超过“足够远”阈值后开始刷新,而不是在用户释放拖动时开始。
为了实现此目的,您需要修改-refresh:
方法以检查控件何时转换为refreshing
状态:
-(void)refresh:(id)sender {
UIRefreshControl *refreshControl = (UIRefreshControl *)sender;
if(refreshControl.refreshing) {
(... refresh code ...)
}
}
请注意,您为(... 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
});
});
}
}
将控制事件更改为UIControlEventTouchUpInside
将不起作用,因为UIRefreshControl
不是要与之直接交互的UI组件。用户永远不会触摸 UIRefreshControl
,因此无法触发UIControlEventTouchUpInside
事件。
答案 2 :(得分:2)
使用NSRunLoop
可以将刷新安排为仅在手指抬起时进行。用数组中的-(void)performInModes:(NSArray<NSRunLoopMode> *)modes block:(void (^)(void))block;
调用NSRunLoopDefaultMode
。
在触摸保持不变的情况下,运行循环模式为UITrackingRunLoopMode
,仅在提起后才会恢复为默认状态。