在使应用程序处于非活动状态后,UIRefreshControl停止旋转

时间:2014-02-13 15:46:42

标签: ios cocoa-touch uitableview uirefreshcontrol

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

在长时间运行操作期间,按“主页”按钮使应用程序处于非活动状态。之后,我再次激活应用程序。微调器冻结(停止旋转),无法将其恢复到初始状态。

如何解决?

5 个答案:

答案 0 :(得分:21)

我认为这是一个有点延迟的答案但是,今天我在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;
    }
}

答案 1 :(得分:10)

这对我有用

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
    }
}

答案 2 :(得分: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
        }
    }
}

答案 3 :(得分:0)

这仍然是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 :(得分:0)

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

我开始思考为什么 iOS 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 添加类似的代码。