In my app I have a view that extends UIScrollView and populates its content as the user scrolls. However, if the user scrolls too fast the views being populated inside the UIScrollView don't get created on time and you can actually see the UIScrollView's background. The reason why this happens is because I'm doing this lazy loading in the layoutSubviews doesn't seem to get called every time the contentOffset property is changed.
If you scroll the UIScrollView slowly you don't run into the problem I described above and the content is loaded quickly enough.
The only solution to this problem that I can think of is by making it so the UIScrollView doesn't scroll faster than a certain speed when the user lifts up his finger from the screen.
Just so you know changing the decelerationRate property isn't my solution. DecelerationRate tells the UIScrollView how fast it needs to stop scrolling after the user lifts up the finger.
scroll.pagingEnabled = YES;
I had the exact same issue. I solved it with a two way approach (iOS 8.3, Swift 1.2):
Preparation
Add the scrollview delegate to your class:
class myCustomClassName:UIViewController,UIScrollViewDelegate
{
}
Made my class the delegate for the scrollview:
self.myScrollView.delegate = self
Added the delegate method in which i get the contentOffset (scrolled position):
func scrollViewDidScroll(scrollView: UIScrollView)
{
//some code...
}
Added "content ranges" with bool checks if the data has already beend added:
func scrollViewDidScroll(scrollView: UIScrollView)
{
//Total products = TP
if self.useScrollViewDynamicLoading
{
var scrollPosition:CGFloat = scrollView.contentOffset.y
switch scrollPosition
{
case 200.0...300.0:
//TP = 24
if self.checkIfProductsInGivenRangeHaveAlreadyBeenAdded(18)
{
loadProductsForProductRange(12)
}
case 600.0...700.0:
//TP = 36
if self.checkIfProductsInGivenRangeHaveAlreadyBeenAdded(24)
{
loadProductsForProductRange(18)
}
}
....
In viewDidLoad()
changed the scrollview deceleration rate:
self.myScrollView.decelerationRate = 0.5