一尘不染

Swift viewWillTransition未调用

swift

我正在使用创建全屏图片库UICollectionView。当用户旋转设备,我执行更新的UICollectionView

func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)

我以UIViewController模态呈现,并UICollectionView占据了全屏。在中viewDidLoad,我将流程布局创建为:

let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal
flowLayout.minimumInteritemSpacing = 0
flowLayout.minimumLineSpacing = 0
photosCollectionView.isPagingEnabled = true
photosCollectionView.setCollectionViewLayout(flowLayout, animated: true)

我也有这样的大小:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return photosCollectionView.frame.size
}

当我旋转设备时,viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)它永远不会被调用,这将导致UICollectionViewLayout无法更新。旋转设备时,确实收到消息:

The behavior of the UICollectionViewFlowLayout is not defined because: the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.

我已在线阅读可以添加的内容:

self.automaticallyAdjustsScrollViewInsets = false

UIViewController,但已经没有影响。没有任何内容或版块插图UICollectionView

我也有super.viewWillTransition在函数内的被调用。谁能协助我解决造成此问题的原因?


阅读 693

收藏
2020-07-07

共1个答案

一尘不染

如果您只关心设备旋转时的布局,请使用:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    collectionView.collectionViewLayout.invalidateLayout()
    collectionView.layoutIfNeeded()
}

从苹果文档:

public func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)

当视图控制器的视图大小由其父级更改时(即,其窗口旋转或调整大小时,对于根视图控制器),将调用此方法。如果重写此方法,则应调用super将更改传播给子级,或手动将更改转发给子级。

我猜您可能在该视图的父级上调用了此函数而未调用super

解决方法还包括注册设备旋转:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChange), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    NotificationCenter.default.removeObserver(self)
}

func deviceOrientationDidChange(_ notification: Notification) {
    let orientation = UIDevice.current.orientation
    print(orientation)
}
2020-07-07