我已经创建了一个UICollectionView,这样我就可以将视图排列成整齐的列.我希望在> 500像素宽的设备上有一个列.
为了实现这一点,我创建了这个函数:
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { let size = collectionView.frame.width if (size > 500) { return CGSize(width: (size/2) - 8, height: (size/2) - 8) } return CGSize(width: size, height: size) }
这在第一次加载时按预期工作,但是当我旋转设备时,计算并不总是再次发生,并且视图并不总是按预期重绘.这是设备旋转时的代码:
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) { collectionView.collectionViewLayout.invalidateLayout() self.view.setNeedsDisplay() }
我假设我忘了重绘一些东西,但我不确定是什么.任何想法都非常感谢收到!
也许最直接的方法是在viewWillTransitionToSize期间使invalidateLoutout:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) guard let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else { return } flowLayout.invalidateLayout() }
你可能会用viewWillLayoutSubviews
.这个问题应该是有用的,但只要视图控制器视图即将布局其子视图,就会以低音方式调用此问题.
所以你的代码看起来像这样:
override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() guard let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else { return } if UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication().statusBarOrientation) { //here you can do the logic for the cell size if phone is in landscape } else { //logic if not landscape } flowLayout.invalidateLayout() }
我倾向于使用viewWillTransitionToSize
相同的东西,只是invalidateLayout()
在那里打电话.
要使集合视图调整其单元格的大小并在旋转过程中使更改生效,请使用过渡协调器:
(迅捷4+)
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) // Have the collection view re-layout its cells. coordinator.animate( alongsideTransition: { _ in self.collectionView.collectionViewLayout.invalidateLayout() }, completion: { _ in } ) }
traitCollectionDidChange
也可以使用方法代替viewWillLayoutSubviews
:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) guard let previousTraitCollection = previousTraitCollection, traitCollection.verticalSizeClass != previousTraitCollection.verticalSizeClass || traitCollection.horizontalSizeClass != previousTraitCollection.horizontalSizeClass else { return } if traitCollection.horizontalSizeClass == .regular && traitCollection.verticalSizeClass == .regular { // iPad portrait and landscape // do something here... } if traitCollection.horizontalSizeClass == .compact && traitCollection.verticalSizeClass == .regular { // iPhone portrait // do something here... } if traitCollection.horizontalSizeClass == .regular && traitCollection.verticalSizeClass == .compact { // iPhone landscape // do something here... } collectionView?.collectionViewLayout.invalidateLayout() collectionView?.reloadData() }