gpt4 book ai didi

ios - 设备旋转后的 UICollectionView contentOffset

转载 作者:IT王子 更新时间:2023-10-29 05:22:25 28 4
gpt4 key购买 nike

我正在尝试做的事情:

在 Apple 的 Photo 应用程序中,如果您在滚动到任意偏移量的同时旋转设备,则之前位于中心的同一单元格将在旋转后最终位于中心。

我正在尝试使用 UICollectionView 实现相同的行为。 'indexPathsForVisibleItems' 似乎是这样做的方式......

到目前为止我得到了什么:

以下代码提供了旋转之间的平滑操作,但中心项目计算似乎已关闭:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)

self.collectionView?.collectionViewLayout.invalidateLayout()

let middleItem = (self.collectionView?.indexPathsForVisibleItems.count / 2) - 1
let indexPath = self.collectionView?.indexPathsForVisibleItems[middleItem]

coordinator.animate(alongsideTransition: { ctx in

self.collectionView?.layoutIfNeeded()
self.collectionView?.scrollToItem(at: indexPath!, at: .centeredVertically, animated: false)

}, completion: { _ in


})
}

以上代码不能使用的地方:

  1. Portrait -> Landscape:与最终应该位于中心的单元格有些偏离。
  2. Portrait -> Landscape -> Portrait:完全偏离 Portrait 中最初的偏移量。
  3. Portrait -> Landscape -> Portrait -> Landscape:走开!

注意事项:

  • 由于以下原因,我必须在旋转时使 Collection View 布局无效必须重新计算单元格大小和间距。
  • self.collectionView?.layoutIfNeeded() 在动画中
    阻止,使过渡平滑
  • 可能是 scrollToItem 在 Collection View 之前被调用布局未最终确定,导致滚动偏移不正确?

替代方法?

不使用“indexPathsForVisibleItems”,而只使用“contentOffset”?计算offset旋转后offset?但是,当旋转后的 contentSize 可能与对不同单元格大小、单元格间距等的预期不同时,这怎么可能呢?

最佳答案

您可以通过实现 UICollectionViewDelegate 来做到这一点方法 collectionView(_:targetContentOffsetForProposedContentOffset:) :

During layout updates, or when transitioning between layouts, the collection view calls this method to give you the opportunity to change the proposed content offset to use at the end of the animation. You might return a new value if the layout or animations might cause items to be positioned in a way that is not optimal for your design.

或者,如果您已经子类化了 UICollectionViewLayout,您可以实现 targetContentOffset(forProposedContentOffset:)在您的布局子类中,这可能更方便。

在该方法的实现中,计算并返回将导致中心单元格位于 Collection View 中心的内容偏移量。如果您的单元格大小是固定的,那么撤消由其他 UI 元素(例如状态栏和/或导航栏的消失框架)引起的内容偏移更改应该是一件简单的事情。

如果您的单元格大小因设备方向而异:

  1. 在设备旋转之前,通过调用 indexPathForItem(at:) 获取并保存中心单元格的索引路径在您的 Collection View 上,将内容偏移量(加上 Collection View 可见边界高度的一半)作为点传递。
  2. 实现 targetContentOffset(forProposedContentOffset:) 方法之一。通过使用保存的索引路径调用 layoutAttributesForItem(at:) 来检索中心单元格的布局属性。目标内容偏移量是该项目的框架中间(小于 Collection View 可见边界高度的一半)。

第一步可以在您的 View Controller 中的 viewWillTransition(to:with:)scrollViewDidScroll() 中实现。它也可以在 prepareForAnimatedBoundsChange() 中的布局对象中实现,或者在检查由设备方向变化引起的边界变化后在 invalidateLayout(with:) 中实现。 (您还需要确保 shouldInvalidateLayout(forBoundsChange:) 在这些情况下返回 true。)

您可能需要针对内容插入、单元格间距或其他特定于您的应用的事项进行调整。

关于ios - 设备旋转后的 UICollectionView contentOffset,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41639968/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com