UICollectionViewDelegateFlowLayout函数sizeForItemAt何时调用?



我正在尝试以编程方式根据方向动态更改集合单元格的大小。我使用sizeForItemAt函数这样做,但我只发现它被调用时,设备方向进入横向模式。我应该使用这种方法还是可以使用不同的方法来实现?

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let sectionAttributes = SectionAttributesFactory.createSectionAttributes(for: indexPath.section)

if UIDevice.current.orientation.isLandscape {
print("Section: (sectionAttributes.type) | lanscape: (sectionAttributes.cellLayout.landscapeSize.width)")
} else {
print("Section: (sectionAttributes.type) | portrait: (sectionAttributes.cellLayout.portraitSize.width)")
}
}

collectionView(_:layout:sizeForItemAt:)在viewController首次加载和collectionView的布局无效时被调用。您通常想要使viewWillTransition(to:with:)

中的布局无效
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { context in
self.collectionView.collectionViewLayout.invalidateLayout()
})
}

然后你可以根据设备方向和视图大小更改单元格大小:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let cellsPerRow = UIDevice.current.orientation.isPortrait ? CGFloat(3.0) : CGFloat(4.0)
let spacing = layout.minimumInteritemSpacing * (cellsPerRow - 1)
let cellWidth = (view.frame.size.width - spacing) / cellsPerRow
return .init(uniform: cellWidth)
}