Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIRefreshControl jump and flash issues

I have a UITableViewController with the built-in UIRefreshControl. I have two issues with the refresh animation which I want to fix.

  1. When I drag and pull the table view, it starts to update data from our server. If the user keeps it dragging, a noticeable offset jump occurs.

  2. When the refresh operation ends, the table view hides the refresh control animated. After it finishes hiding it, the control flashes for a a few frames.

Showcase

The control is set up from UIStoryboard. I set up target and tint color from there. When the action fires my code refreshes the data from our server, which has a callback when the server responds. I stop the refresh control from there:

dispatch_async(dispatch_get_main_queue(), ^{
   [self.refreshControl endRefreshing];
});
...
[self.tableView reloadData];

Is something I do wrong or UIRefreshControl is just buggy in iOS 11?

like image 919
gklka Avatar asked Jun 28 '18 09:06

gklka


2 Answers

The UIRefreshControl is kind of mysterious at this point (it is affected by many things - do you use large titles, set the refreshControl in viewDidLoad or elsewhere etc.)

The best way to get rid of these issues is to stop observing valueChanged of the UIRefreshControl and do reloadData / endRefreshing after you're sure there is no dragging (e.g. scrollViewDidEndDragging).

Also I was able to reproduce the activity indicator flickering of UIRefreshControl from your gif this way (and only for iPhone X-like devices with no navigation bar translucency):

edgesForExtendedLayout = [.top]
extendedLayoutIncludesOpaqueBars = true

then all I had to do was changing the edgesForExtendedLayout and extendedLayoutIncludesOpaqueBars.

like image 35
Jakub Truhlář Avatar answered Sep 21 '22 14:09

Jakub Truhlář


I was experiencing a similar issue and this is how I finally fixed it:

  1. The 'estimated row height' property needs to be set. Otherwise, reloadData() causes a noticeable jump. This is explained here

  2. Calling endRefreshing() while the user is still dragging also results in a noticeable jump. To avoid this:

    • When I receive new data from the server, I check if the user is still dragging (UIScrollView.isDragging). If this is the case then I don't call endRefreshing() immediately, but set a flag instead.
    • I override scrollViewDidEndDragging and check the flag there; if set, then I call endRefreshing() and clear the flag.
like image 199
Grodriguez Avatar answered Sep 21 '22 14:09

Grodriguez