I'm having some trouble on implementing a UIRefreshControl on a UITableView.
Everything is working fine except the fact that I have to scroll something like 80% of the screen for the UIRefreshControl to get triggered. Sometimes I'm not even able to trigger it since there is a tab bar on the bottom of the screen, which cancels the scrolling movement when the finger reaches it.
I've looked at other apps, namely Apple's 'Mail', where the UIRefreshControl is triggered after scrolling only 30% of the screen.
What am I missing? Really need help on this one!
Thanks in advance
You probably need to not use UIRefreshControl and just utilize scrollViewDidScroll (or tableViewDidScroll if a tableView) on handle your refresh accordingly since UIRefreshControl can't be modified.
I had a similar problem and it's quite possible that's the same cause for you. For me happens that I hided the scroll indicator making me unable to see the obvious cause of the problem: the
UIScrollView
's height is much greater than itssuperView
...Double check your
UIScrollView
's height because the "dragging distance" it's just a percentage of that height. Same goes forUITableView
too, since it's a child class ofUIScrollView
.EDIT: Seems that this isn't the only way to reproduce this problem, since the required drag distance to trigger the refresher is calculated in a buggy way. Refer to this question for more info.
But in general it will happen if your
UIScrollView
's height is different than his parent container (e.g the screen itself).After some extensive testing and playing around with UIKit I have come to a conclusion.
TL;DR
UIRefreshControl
isn't smart enough. To fix add this code inviewDidAppear
orviewDidLayoutSubviews
Test setup
Single
UIViewController
in a Storyboard with aUIView
as itsview
which in turn has aUIScrollView
as only subview which in turn has a singleUIView
as subview withtop,right,bottom,left,width,height
constraints equal tosuperview
. The viewController has freeform size with1200p
height.In the subclass of the
UIViewController
aUIRefreshControl
is added by setting theUIScrollView#refreshControl
to a newUIRefreshControl
insideviewDidLoad
.When running the application in an
iPhone X simulator
and dragging the scrollView to perform a "Pull to refresh" one must drag considerably longer to make the refreshControl animating and send its notification it was pulled down.The problem
One of my hypotheses was that the
UIRefreshControl
gets itsdragging distance
set once it is added to the scrollView and sinceAutoLayout
hasen't updated the root view's subviews atviewDidLoad
the scrollView has a height of1180.0p
instead of the correct768.0p
thus the refreshControl'sdragging distance
would be calculated for the height1180.0p
instead of768.0p
and thus become much longer than expected when running the app.The solution
By updating the scrollView's refreshControl after the correct size for the scrollView has been set the correct dragging distance is calculated.
This update has to occur in a function where the correct size of the scrollView has been calculated, for example
viewDidAppear
andviewDidLayoutSubviews
.