【问题标题】:What are some good ways to retain mutiple UICollectionView's scroll position within a UIPageViewController?在 UIPageViewController 中保留多个 UICollectionView 滚动位置的好方法是什么?
【发布时间】:2020-12-29 12:29:13
【问题描述】:

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

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

但是,从屏幕录制中可以看出,每次我们作为当前页面向后滑动时,UICollectionView 的滚动位置都会“丢失”。

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

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

谢谢。

【问题讨论】:

    标签: ios swift uicollectionview


    【解决方案1】:
    1. iOS 是否提供任何底层框架供我们实现这一目标?

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

    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. 如果我们需要手动做,什么时候应该将UICollectionView的滚动位置保存在全局变量中? viewDidUnload 似乎不再被调用。

    您可以在viewWillDisappear 或集合视图委托调用scrollViewDidScroll 时保存值

    1. 什么时候是恢复滚动位置的好时机?视图加载? viewDidLoad 是开始的好主意,但不能保证布局会准备好。您可以在viewWillAppear 或致电collectionView.reloadData() 后重试

    【讨论】:

    • 我通过调用collectionView.contentOffset = CGPoint(x: self.collectionView.contentOffset.x, y: 100) 快速尝试一下,然后在viewWillLayoutSubviews 中调用collectionView.layoutIfNeeded()。但没有观察到任何滚动效果。不知道为什么...
    • 在collectionView上尝试setContentOffset()
    • 并且您要确保滚动 视图 Did 布局其子视图。例如viewWillAppear
    • 对不起,我用viewDidLayoutSubviews误导了你,这个方法不存在。我的意思是viewWillAppear
    • 谢谢。以下代码 sn-p 适用于我的情况 - gist.github.com/yccheok/41d56a68ef6eddfa76a13a87d7515851
    猜你喜欢
    • 1970-01-01
    • 2020-03-14
    • 1970-01-01
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多