4
votes

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.

2
Why don't/can't you do what apple does in the maps and safari apps, and just display an abstract background for unloaded content?Jonathan
I could certainly do that but that wouldn't look good in this app at all.ForeignerBR
Have you ever found a solution for that?Aloha Silver
Have you got a solution for thatG.Abhisek

2 Answers

1
votes

scroll.pagingEnabled = YES;

0
votes

I had the exact same issue. I solved it with a two way approach (iOS 8.3, Swift 1.2):

  1. 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...
      }
      
  2. 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)
                }
            }
            ....
    
  3. In viewDidLoad() changed the scrollview deceleration rate:

    self.myScrollView.decelerationRate = 0.5