UIRefreshControl - 如何在触摸释放后进行刷新操作?

out*_*ase 29 iphone objective-c ios uirefreshcontrol

长时间监听,第一次调用这里堆栈溢出.要温柔.

我在UITableView上实现UIRefreshControl来刷新表的数据.在其他拉动刷新实现中,刷新过程不会开始,直到用户的手指在拉动刷新距离内被抬起.UIRefreshControl似乎没有立即显示它.

我的UIRefreshControl初始化代码:

UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];
[self.tableView addSubview:refreshControl];
Run Code Online (Sandbox Code Playgroud)

我的刷新:代码是相当基本的:

-(void)refresh:(id)sender {
(... refresh code ...)
[sender endRefreshing];
}
Run Code Online (Sandbox Code Playgroud)

如何延迟刷新:功能,直到用户从拉动中移开手指?

Ned*_*Ned 38

我也遇到了同样的问题.我认为我的方法不是很好,但看起来很有效.

  1. 在里面 UIRefreshControl

    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
    self.refreshControl = refreshControl;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 检查UIRefreshControl用户完成拖动表的状态(UITableViewDelegate符合UIScrollViewDelegate)

    - (void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView
    {    
        if( self.refreshControl.isRefreshing )
            [self refresh];
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 更新表

    - (void)refresh
    {
        [self.refreshControl endRefreshing];
    
        // TODO: Update here your items
    
        [self.tableView reloadData];
    }
    
    Run Code Online (Sandbox Code Playgroud)

希望它会对你有所帮助.


小智 21

UIRefreshControl已经有"适当"时间开始的住宿.pull-to-refresh控件的正确行为是在用户超过"足够远"阈值后开始刷新,而不是在用户释放拖动时.

为了实现此目的,您需要修改-refresh:方法以检查控件何时转换为refreshing状态:

-(void)refresh:(id)sender {
    UIRefreshControl *refreshControl = (UIRefreshControl *)sender;
    if(refreshControl.refreshing) {
        (... refresh code ...)
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,您为自己调用的任何方法都(... 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
            });
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

将控件事件更改为UIControlEventTouchUpInside不起作用,因为UIRefreshControl它不是要与之直接交互的UI组件.用户永远不会UIRefreshControl,所以没有UIControlEventTouchUpInside事件可以触发.


DrM*_*uer 5

可以通过使用 来安排刷新仅在手指抬起时发生NSRunLoop。在数组中调用-(void)performInModes:(NSArray<NSRunLoopMode> *)modes block:(void (^)(void))block;with 。NSRunLoopDefaultMode

当触摸仍然保持时,运行循环模式为UITrackingRunLoopMode,只有在抬起后才会返回默认状态。