我有一个分页的,水平滚动的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()
}
实际上,如果我在invalidateLayout()
中拨打viewWillLayoutSubviews
,则无需在此处设置itemSize
,因为重新布局时将调用sizeForItemAtIndexPath
在设置新的itemSize之后,我还尝试在旋转期间手动滚动到第一个可见单元格,但这没有任何改进:
if let item = collectionView.indexPathsForVisibleItems().first {
collectionView.scrollToItemAtIndexPath(item, atScrollPosition: .CenteredHorizontally, animated: true)
}
答案 0 :(得分:8)
您应该处理UICollectionView
的内容偏移,因此在视图控制器中尝试覆盖viewWillTransitionToSize
协议中的UIContentContainer
函数,如下所示:
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)
}