【问题标题】:UIRefreshControl endRefreshing is not smoothUIRefreshControl endRefreshing 不流畅
【发布时间】:2015-04-18 01:32:35
【问题描述】:

当我的数据已完成加载并且我的 tableView 已重新加载时,我在刷新控件上调用 endRefreshing,然后它从其加载状态“跳跃”并消失 - 我如何实现一个平滑的动画,使刷新控件滑开时完成了吗?

【问题讨论】:

    标签: ios user-interface animation tableview


    【解决方案1】:

    我正在添加一个新答案,因为唯一的答案在解释上不是很精确。而这对于 cmets 来说可能太过分了。

    Halpo 的解决方案是正确的。但是上面的理由是错误的。

    调用-[NSObject (NSDelayedPerforming) performSelector:withObject:afterDelay:]保证调用在下一次runloop迭代中执行。

    所以这不起作用,因为有一个小的延迟,但你正在将它移动到下一个循环。

    实际上,您可以/可以将延迟减少到0.0,它仍然可以工作。此外,更正确的(就使用旨在实现某事的对象而言,而不是更好的结果)实现是可能的。

    这里是各种代码sn-ps:

    // SOLUTION I
    
    [[self tableView] reloadData];
    [[self refreshControl] performSelector:@selector(endRefreshing) withObject:nil afterDelay:0.0];
    
    // SOLUTION II (semantically correct)
    
    [[self tableView] reloadData];
    [[NSOperationQueue currentQueue] addOperationWithBlock:^{
        [[self refreshControl] endRefreshing];
    }];
    
    // SOLUTION III (GCD)
    
    dispatch_async(dispatch_get_main_queue(), ^{
        [[self refreshControl] endRefreshing];
    }];
    

    编辑

    正如johann-fradj 所指出的,您也可以使用 GCD。我非常喜欢 GCD,但我认为,解决方案 II 最能描述正在发生的事情。此外,GCD 不是很 Objective-C-ish,所以我个人宁愿坚持我的解决方案。

    【讨论】:

    • 这应该是正确的答案。您也可以在主队列中简单地 dispatch_async。
    • 有趣的是,解决方案 1 有效,但解决方案 2 无效。主队列上的 Dispatch_async 也没有。
    • @JohannFradj 感谢您的意见,我将其添加到我的答案中。但正如我在评论中指出的那样,我不会在这里使用它;-)
    • GCD 解决方案一直在为我工作,但后来停止了。即使是解决方案 II 也会导致动画不连贯。也就是说,在完成块中使用 [refreshControl endRefreshing] 重新加载 tableview 时提交 CATransaction 会产生非常流畅的动画。我承认这感觉像是一种 hack,因为据我所知 [tableView reloadData] 是不可动画的,但这是在我的特定情况下唯一有效的解决方案。
    • 奇怪的是它停止工作了。交易方式很有趣,我一定会尝试一下,看看我是否喜欢它。 “停止工作”是什么意思?您是在谈论特定的 iOS 更新吗?
    【解决方案2】:

    修复了问题 - 我在重新加载数据后对 endRefresh 添加了一个微小的延迟:

    [self.tableView reloadData];
    [self.refreshControl performSelector:@selector(endRefreshing) withObject:nil afterDelay:0.05];
    

    【讨论】:

    • "endRefreshing" 刷新完成后必须显式调用
    • 我说一旦数据源加载了数据,就必须调用“endRefreshing”。但它应该在重新加载 TableView 或 CollectionView 之前调用,否则会产生奇怪的错误和卡顿效果。
    • 在 Swift 中:self.refreshControl.perform(#selector(UIRefreshControl.endRefreshing), with: nil, afterDelay: 0)
    【解决方案3】:

    Swift 4 解决方案

        tableView.reloadData()
        if refreshControl?.isRefreshing == true {
            DispatchQueue.main.async {
                self.refreshControl?.endRefreshing()
            }
        }
    

    其他解决方案(延迟,使用 CATransaction,...)更复杂,没有任何明显的优势

    【讨论】:

      【解决方案4】:

      尝试将调用 endRefreshing() 包装在 UIView 动画块中:

      我也遇到过这个问题。对于endRefreshing() 文档说明:

      UIView.animateWithDuration(0.5) {
          self.refreshControl.endRefreshing()
      }
      

      文档说明:

      如果还启用了动画,则使用动画隐藏控件。

      【讨论】:

        【解决方案5】:

        其中一个原因可能是您在调用 endRefresh 后刷新了表格视图。例如,我的电话过去看起来像这样:

        [self.refreshControl beginRefreshing];
        [self.network getThings:^(id things, NSError *error) {
            [self.refreshControl endRefreshing];
        
            if (error) {
                ...
            } else {
                self.things = things;
                [self.tableView reloadData];
            }
        }];
        

        这很糟糕,因为在 endRefresh 动画运行时表格会自行更新。所以正确完成的代码如下所示:

        [self.refreshControl beginRefreshing];
        [self.network getThings:^(id things, NSError *error) {
            if (error) {
                [self.refreshControl endRefreshing];
                ...
            } else {
                self.things = things;
                [self.tableView reloadData];
                [self.refreshControl endRefreshing];
            }
        }];
        

        【讨论】:

        • 只是给代码设计一点“教训”:在 else 关闭之后调用 endRefreshing 。您将使您的代码“更小”并且更具可读性。此外,如果您只对开发过程中的错误原因感兴趣(您不应该这样做),您可以简单地反转 if 并使用更少的代码。
        • 你说得对,朱利安。复制的代码片段如下所示,因为“...”需要在 endRefreshing 动画之后运行 :) 在这个特定示例中,您建议的方法会更好。
        【解决方案6】:

        我的解决方案是在调用tableView.reloadData()之前运行refreshControl?.endRefreshing()

        refreshControl?.endRefreshing()
        tableView.reloadData()
        

        当调用endRefreshing() 是在调用reloadData() 之后,每当重新加载数据时,TableView 就会跳转。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-15
          • 1970-01-01
          • 2019-07-06
          • 1970-01-01
          相关资源
          最近更新 更多