UIRefreshControl stops spinning after making application inactive

一世执手 提交于 2019-12-08 14:50:16

问题


I use UIRefreshControl in a UITableView:

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

With refresh handler:

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

During the long running operation I make the application inactive pressing Home button. After that I make the application active again. The spinner freezes (stops spinning) and there is no way to return it to the initial state.

How to fix it?


回答1:


I think it is a bit delayed answer but , today I saw similar issue on ios 7 , ios 6 continued spinning ,

here is a little workaround for this

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

it will stop and start again spinning , but it only happened on ios7 with me , so maybe you should check not to do it on 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;
    }
}



回答2:


This is what worked for me

Swift 3 and 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
    }
}



回答3:


In iOS 11 this approach works much better than the others

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



回答4:


This still is an issue in iOS11. The solution needs to be modified a bit though, otherwise the refresh control will spin too fast

- (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;
        });
    }
}


来源:https://stackoverflow.com/questions/21758892/uirefreshcontrol-stops-spinning-after-making-application-inactive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!