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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 22:50:23  来源:igfitidea点击:

UIRefreshControl - How do I make the refresh action occur after the touch is released?

iphoneiosobjective-cuirefreshcontrol

提问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.

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

  1. Init UIRefreshControl

    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
    self.refreshControl = refreshControl;
    
  2. Check state of UIRefreshControlwhen user finish dragging the table (UITableViewDelegateconforms to UIScrollViewDelegate)

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

    - (void)refresh
    {
        [self.refreshControl endRefreshing];
    
        // TODO: Update here your items
    
        [self.tableView reloadData];
    }
    
  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];
    }
    

Hope it will help you.

希望它会帮助你。

回答by outphase

UIRefreshControlalready 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 refreshingstate:

为了实现这一点,您需要修改您的-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 -endRefreshingat 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 UIControlEventTouchUpInsidewill not work because UIRefreshControlis not a UI component intended to be directly interacted with. The user will never touchthe UIRefreshControl, so no UIControlEventTouchUpInsideevent 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 NSRunLoopDefaultModein 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,它只会在升空后恢复到默认值。