【问题标题】:UIRefreshControl stops spinning after making application inactiveUIRefreshControl 在使应用程序处于非活动状态后停止旋转
【发布时间】:2014-03-12 14:32:37
【问题描述】:

我在 UITableView 中使用 UIRefreshControl:

UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(refresh)
         forControlEvents:UIControlEventValueChanged]; 
self.refreshControl = refreshControl;

使用刷新处理程序:

-(void)refresh {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // (...some long running operation...)
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.refreshControl endRefreshing];
        });
    });
}

在长时间运行的操作中,我按下主页按钮使应用程序处于非活动状态。之后,我再次使应用程序处于活动状态。微调器冻结(停止旋转)并且无法将其返回到初始状态。

如何解决?

【问题讨论】:

    标签: ios cocoa-touch uitableview uirefreshcontrol


    【解决方案1】:

    我认为这是一个有点延迟的答案,但是,今天我在 ios 7 上看到了类似的问题,ios 6 继续旋转,

    这里有一个小解决方法

    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        if(self.refreshControl.isRefreshing) {
            CGPoint offset = self.tableView.contentOffset;
            [self.refreshControl endRefreshing];
            [self.refreshControl beginRefreshing];
            self.tableView.contentOffset = offset;
        }
    }
    

    它会停止并重新开始旋转,但它只发生在我的 ios7 上,所以也许你应该检查一下不要在 ios6 上这样做

    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        if(self.refreshControl.isRefreshing && [[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
            CGPoint offset = self.tableView.contentOffset;
            [self.refreshControl endRefreshing];
            [self.refreshControl beginRefreshing];
            self.tableView.contentOffset = offset;
        }
    }
    

    【讨论】:

    • 这个工作,虽然 refreshControl 失去了它的自定义 tintColor。它在启动时变为默认灰色
    【解决方案2】:

    这对我有用

    Swift 3 和 Swift 4:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        if self.refreshControl?.isRefreshing == true {
            let offset = self.tableView.contentOffset
    
            self.refreshControl?.endRefreshing()
            self.refreshControl?.beginRefreshing()
            self.tableView.contentOffset = offset
        }
    }
    

    Swift 2.3:

     override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
    
        if self.refreshControl?.refreshing == true {
            let offset = self.tableView.contentOffset
    
            self.refreshControl?.endRefreshing()
            self.refreshControl?.beginRefreshing()
            self.tableView.contentOffset = offset
        }
    }
    

    【讨论】:

    • 谢谢 - 这解决了它!但是:动画停止时,tableview 中会出现短暂的闪烁。似乎以某种方式未正确设置内容偏移量。无论如何:它也可以在不为我重置偏移量的情况下工作。
    • @beseder 你找到解决闪烁的方法了吗?
    • 你不需要那些self. ;)
    【解决方案3】:

    这仍然是 iOS11 中的一个问题。解决方案需要稍作修改,否则刷新控件会旋转得太快

    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        if(self.refreshControl.isRefreshing) {
            CGPoint offset = self.tableView.contentOffset;
            [self.refreshControl endRefreshing];
    
            // Delay the restart
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self.refreshControl beginRefreshing];
                self.tableView.contentOffset = offset;
            });
        }
    }
    

    【讨论】:

      【解决方案4】:

      在 iOS 11 中,这种方法比其他方法效果更好

      class AMRefreshControl: UIRefreshControl {
      
          override func didMoveToWindow() {
              super.didMoveToWindow()
      
              if window != nil && isRefreshing, let scrollView = superview as? UIScrollView {
                  let offset = scrollView.contentOffset
                  UIView.performWithoutAnimation {
                      endRefreshing()
                  }
                  beginRefreshing()
                  scrollView.contentOffset = offset
              }
          }
      }
      

      【讨论】:

      • UIView.performWithoutAnimation 在我的情况下是必要的。谢谢
      【解决方案5】:

      我是 Xamarin 开发人员,在 ListView + TabbedPage 上遇到了这个问题,它在 iOS 上使用 UITableView + UIRefreshControl。只有第一个标签页具有良好的旋转 AcitivityIndi​​cator(刷新控件),但该控件在其他标签页上被冻结。

      我开始思考为什么 iOS 有这个“bug”已经 10 年了? 此问题的根本原因是 iOS 不允许在后台使用不可见的动画刷新控件,否则会降低设备性能而无济于事。

      所以我得到了修复它的正确方法:仅在页面可见时显示刷新控件,并在页面隐藏时将其隐藏。

      在 Xamarin 中:

      protected override void OnAppearing()
      {
          base.OnAppearing();
          MyActivityIndicator.IsVisible = IsBusy;
      }
      
      protected override void OnDisappearing()
      {
          base.OnDisappearing();
          MyActivityIndicator.IsRefresh = false;
      }
      
      public bool IsBusy
      {
        ...
          set
          {
              ...
              if(IsVisible) MyActivityIndicator.IsRefresh = value;
          }
      }
      

      我在 ListView.FooterTemplate 中添加了 MyActivityIndi​​cator 以指示加载页面,并在收到刷新命令并清除 ListView 项目后立即将 ListView.IsRefresh 设置为 false。如果需要在列表数据上方显示刷新控件,应该在上面的代码示例中为 ListView.IsRefresh 添加类似的代码。

      【讨论】:

        猜你喜欢
        • 2013-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-13
        • 1970-01-01
        • 2015-03-20
        • 1970-01-01
        相关资源
        最近更新 更多