UIRefreshControl Stuck After Switching Tabs in UIT

2019-01-17 20:28发布

I have a UITableViewController as the root view controller in a UINavigationController, which is in turn one of the view controllers in a UITabBarController. All hooked up in Storyboard.

I've configured the UIRefreshControl for my table in Storyboard as well, and normally it looks like it should when pulling:

Normal UIRefreshControl

However, if I switch between my other tabs once or twice, it looks like this:

Buggy UIRefreshControl

It's not spinning or anything, just stuck "full", and it stays that way until I pull fully and trigger a refresh.

Any ideas or suggestions appreciate.

16条回答
爷、活的狠高调
2楼-- · 2019-01-17 21:10

While refresh control is spinning, if you present some other controller and come back before "end refreshing"; refresh animation will be stuck.

None of the answers above worked for me, and I didn't want to set bool and follow it through all lifecycle of a view controller.

My solution is adding below code to end of viewWillAppear.

in Objc;

if (self.refreshControl.isRefreshing) {
    [self.refreshControl endRefreshing];
    [self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated: true];
    [self.refreshControl beginRefreshing];
}

in Swift;

if self.refreshControl.isRefreshing {
     self.refreshControl.endRefreshing
     self.tableView.setContentOffset(CGPoint(x: 0, y: self.tableView.contentOffset.y-self.refreshControl.frame.size.height), animated: true)
     self.refreshControl.beginRefreshing;
}

Logic is; whenever it catches refresh control is in the state of animating, it will stop it without knowing it is stuck or not and re-run the animation.

Hope it helps.

查看更多
祖国的老花朵
3楼-- · 2019-01-17 21:10

After running into the same problem several times I decided to make a library for it SwiftPullToRefresh.

As said before, refreshControl needs to be stoped on viewDidDisappear(_:) and started on viewWillAppear(_:).

When programatically starting refreshControl animation, tableView.contentOffset needs to be set to appropriate value.

tableView.setContentOffset(CGPoint(x: 0, y: -(refreshControl?.bounds.height ?? 60) - topOffset), animated: true)

var topOffset: CGFloat {
    if let navigationBar = navigationController?.navigationBar, navigationBar.isTranslucent == true {
        return navigationBar.bounds.height + UIApplication.shared.statusBarFrame.height
    } else {
        return 0
    }
}
查看更多
成全新的幸福
4楼-- · 2019-01-17 21:13

The following solution may help you.

CGFloat yTableViewOffset;

- (void)viewDidLoad {

      yTableViewOffset = kNilOptions;
}
- (void)viewWillAppear:(BOOL)animated
{
   if(yTableViewOffset != kNilOptions) {

     CGPoint offset = CGPointMake(tableView.contentOffset.x, yTableViewOffset);
     [refreshControl beginRefreshing];
     tableView.contentOffset = offset;

  }
}
- (void)viewWillDisappear:(BOOL)animated
{
   if(refreshControl.isRefreshing) {
     yTableViewOffset = tableView.contentOffset.y;
     [refreshControl endRefreshing];
  }
}
查看更多
萌系小妹纸
5楼-- · 2019-01-17 21:13

Simply calling endRefreshing in viewWillDisappear: fixed all the issues for me.

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.refreshControl endRefreshing];        
}

Doing the same thing in viewWillAppear: caused the refresh control to rotate strangely when pulling the table.

查看更多
登录 后发表回答