Cheok Yan Cheng
Cheok Yan Cheng

Reputation: 42670

What are some good ways to retain mutiple UICollectionView's scroll position within a UIPageViewController?

Every-time an UIViewController swiped away from current page, it will be destroyed.

If the UIViewController swiped back again as current page, it will be re-created again.

enter image description here

However, as you can see from the screen recording, the scroll position of UICollectionView is "lost" every-time we swipe back as current page.

I was wondering, what are some good ways, to retain mutiple UICollectionView's scroll position within a UIPageViewController?

  1. Does iOS provide any underlying framework for us to achieve so?
  2. If we need to do it manually, when we should save the scroll position of UICollectionView in a global variable? viewDidUnload seems not being called anymore.
  3. When is the good time to restore the scroll position? viewDidLoad?

Thanks.

Upvotes: 1

Views: 89

Answers (1)

Witek Bobrowski
Witek Bobrowski

Reputation: 4239

  1. Does iOS provide any underlying framework for us to achieve so?

Not really, this will need to be handled manually. Let's say you would introduce some kind of delegate protocol that would be implemented by the root controller.

protocol ScrollPositionDelegate: class {
   func collectionView(_ collectionView: UICollectionView, didChangeScrollPosition point: CGPoint)
}

Then all of the child views would keep weak reference to the delegate

weak var delegate: ScrollPositionDelegate?

And call it whenever the position changes. In root You could identify the which view called the delegate method by using tag property on the collectionView (you would need to set it first within the child screen)

extension RootViewController: ScrollPositionDelegate {
    func collectionView(_ collectionView: UICollectionView, didChangeScrollPosition point: CGPoint) {
        switch collectionView.tag {
        case 1:
            // store scroll position for screen 1
        default:
            return
        }
        // or simply
        scrollPosition[collectionView.tag] = point
        // obviously you would need storage like `scrollPosition: [Int: CGPoint]`
    }
} 
  1. If we need to do it manually, when we should save the scroll position of UICollectionView in a global variable? viewDidUnload seems not being called anymore.

You can either save the values when the viewWillDisappear or when the collection view delegate calls scrollViewDidScroll

  1. When is the good time to restore the scroll position? viewDidLoad? viewDidLoad is good idea to start but there is no guarantee that the layout will be ready. You could try again at viewWillAppear or after you call collectionView.reloadData()

Upvotes: 1

Related Questions