UICollectionView 旋转后屏幕尺寸不正确

Kex*_*Kex 2 ios uicollectionview swift

我的视图控制器中有一个UICollectionView定义如下:

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.minimumLineSpacing = Constants.minimumLineSpacing
layout.minimumInteritemSpacing = Constants.minimumInteritemSpacing

let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.backgroundColor = Constants.backgroundColor
collectionView.contentInset = Constants.collectionViewContentInsets

collectionView.refreshControl = refreshControl
Run Code Online (Sandbox Code Playgroud)

我将单元格大小设置为sizeForItemAt

func collectionView(
    _ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    sizeForItemAt indexPath: IndexPath
) -> CGSize {
    let collectionViewHorizontalInset = Constants.collectionViewInsets.left + Constants.collectionViewInsets.right

    let cellWidth = isPortrait
        ? (screenSize.width - collectionViewHorizontalInset - Constants.minimumInteritemSpacing) / 2.0
        : (screenSize.width - collectionViewHorizontalInset - Constants.minimumInteritemSpacing * 2.0) / 3.0

    return CGSize(width: cellWidth, height: Constants.cellHeight)
}
Run Code Online (Sandbox Code Playgroud)

与 sceneSize 如下:

private var screenSize: CGSize {
    view.bounds.size
}
Run Code Online (Sandbox Code Playgroud)

该属性isPortrait跟踪方向,在viewDidLoad

isPortrait = view.bounds.size.width < view.bounds.size.height
Run Code Online (Sandbox Code Playgroud)

我有以下内容viewWillTransition

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

    isPortrait = size.width < size.height
    collectionView.collectionViewLayout.invalidateLayout()
}
Run Code Online (Sandbox Code Playgroud)

当我旋转设备时,它似乎获得了不正确的屏幕尺寸,因此计算出错误的单元格宽度。例如,如果我横向加载应用程序,每行将有 3 个单元格,这是正确的。但是,如果我然后旋转到纵向并返回到横向,则每行将有 4 个单元格,这是不正确的。

我在这里做错了什么?旋转后如何获得正确的屏幕尺寸?

Kex*_*Kex 6

用对我有用的方法回答我自己的问题:

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

    coordinator.animate { _ in
        self.collectionView.collectionViewLayout.invalidateLayout()
    }
}
Run Code Online (Sandbox Code Playgroud)

看来关键是使用coordinator.animate,这样sizeForItemAt计算时屏幕尺寸才会正确。