参见英文答案 >
Keeping the contentOffset in a UICollectionView while rotating Interface Orientation23个
我有一个分页的,水平滚动的UICollectionView,其中每个单元格占用视图/设备屏幕的大小,并且一次出现一个单元格.我遇到一个问题,在设备旋转时,单元格将转换为正确的新大小,但单元格的位置将关闭.
我有一个分页的,水平滚动的UICollectionView,其中每个单元格占用视图/设备屏幕的大小,并且一次出现一个单元格.我遇到一个问题,在设备旋转时,单元格将转换为正确的新大小,但单元格的位置将关闭.
轮换前:
轮换后:
在旋转时,我怎样才能不仅正确调整集合视图单元格的大小,还要确保当前单元格保持可见?
我把这个问题简化为一个非常简单的例子,没有自定义流布局.
将单元格的大小设置为collectionView框架的大小(集合视图是持有它的视图控制器的大小):
func collectionView(collectionView: UICollectionView,layout collectionViewLayout: UICollectionViewLayout,sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { return collectionView.frame.size }
试图在viewWillLayoutSubviews中处理旋转:
override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() guard let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else { return } flowLayout.itemSize = collectionView.frame.size flowLayout.invalidateLayout() }
实际上,如果我在viewWillLayoutSubviews中调用invalidateLayout(),则不需要在此处设置itemSize,因为在重新创建布局时将调用sizeForItemAtIndexPath.
在设置新的itemSize之后,我还尝试在旋转期间手动滚动到第一个可见单元格,但这没有显示出任何改进:
if let item = collectionView.indexPathsForVisibleItems().first { collectionView.scrollToItemAtIndexPath(item,atScrollPosition: .CenteredHorizontally,animated: true) }
解决方法
您应该处理UICollectionView的内容偏移量,因此在视图控制器中尝试从UIContentContainer协议覆盖viewWillTransitionToSize函数,如下所示:
override func viewWillTransitionToSize(size: CGSize,withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransitionToSize(size,withTransitionCoordinator: coordinator) let offset = yourCollectionView?.contentOffset; let width = yourCollectionView?.bounds.size.width; let index = round(offset!.x / width!); let newOffset = CGPointMake(index * size.width,offset!.y); yourCollectionView?.setContentOffset(newOffset,animated: false) coordinator.animateAlongsideTransition({ (context) in yourCollectionView?.reloadData() yourCollectionView?.setContentOffset(newOffset,animated: false) },completion: nil) }