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

时间:2013-03-23 06:38:49

标签: iphone ios objective-c uirefreshcontrol

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

我在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];
}

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

3 个答案:

答案 0 :(得分:37)

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

  1. 初始UIRefreshControl

    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
    self.refreshControl = refreshControl;
    
  2. 检查用户完成拖动表格后UIRefreshControl的状态UITableViewDelegate是否符合UIScrollViewDelegate

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

    - (void)refresh
    {
        [self.refreshControl endRefreshing];
    
        // TODO: Update here your items
    
        [self.tableView reloadData];
    }
    
  4. 希望它会对你有所帮助。

答案 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,仅在提起后才会恢复为默认状态。