在 UIPageViewController 中保留多个 Collection View 滚动位置的好方法是什么?

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

每次 UIViewController 从当前页面滑开,它都会被销毁。

如果 UIViewController 再次滑回当前页面,将重新创建。

但是,正如您从屏幕录像中看到的那样,每次我们返回当前页面时,UICollectionView 的滚动位置都会“丢失”。

我想知道,有什么好的方法可以在 UIPageViewController 中保留多个 UICollectionView 的滚动位置?

  1. iOS是否为我们提供了实现此目标的任何基础框架?
  2. 如果我们需要手动完成,我们应该什么时候将UICollectionView的滚动位置保存在一个全局变量中? viewDidUnload 似乎不再被调用了。
  3. 什么时候是恢复滚动位置的好时机? viewDidLoad?

谢谢。

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

不一定,这需要手动处理。假设您将引入某种将由根控制器实现的委托协议。

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

那么所有的子视图都会保持对委托的弱引用

weak var delegate: ScrollPositionDelegate?

并在位置发生变化时调用它。在 root 您可以通过在 collectionView 上使用 tag 属性 来识别调用委托方法的视图(您需要先在子屏幕中设置它)

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.

您可以在 viewWillDisappear 或集合视图委托调用 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()