在我的应用程序中,我有一个全屏分页集合视图,每个单元格也需要全屏,因此集合视图布局的项目大小需要与视图控制器视图的边界大小相同。要做到这一点,在viewDidLayoutSubviews
我只是设置项目大小,它按预期工作。当我显示此屏幕时,viewDidLayoutSubviews
被调用3次,每次iPhone 7的视图边界大小为375.0 x 667.0。单元格的大小与预期的大小相同。
但是当使用3D Touch peek和pop来呈现此屏幕时,单元格的大小不是预期的,无论是偷看还是弹出。 viewDidLayoutSubviews
被调用4次,具有这些边界大小:
--- peek triggered ---
375.0 x 569.524495677234
375.0 x 569.524495677234
375.0 x 720.821325648415
--- pop triggered ---
375.0 x 667.0
当偷看时,集合视图为“全屏”,高度为721,单元格的预期宽度为375,但单元格高度为569,应该是721.弹出时,集合视图视图高度按预期更改为667,但单元格高度仍为569。
我在设置collectionView.layoutIfNeeded()
后尝试调用itemSize
,但结果是一样的。为什么集合视图不会更新单元格大小?
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print("\(view.bounds.width) x \(view.bounds.height)")
let boundsSize = CGSize(width: Int(view.bounds.width), height: Int(view.bounds.height))
let flowLayout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
if flowLayout.itemSize != boundsSize {
flowLayout.itemSize = boundsSize
collectionView.layoutIfNeeded() //this doens't help
}
}
答案 0 :(得分:8)
答案 1 :(得分:3)
似乎是UICollectionViewFlowLayout的错误, 我必须在invalidateLayout()之前调用prepare()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else
{
return
}
layout.itemSize = cellSize
layout.minimumLineSpacing = space
layout.prepare() // <-- call prepare before invalidateLayout
layout.invalidateLayout()
}
答案 2 :(得分:0)
尝试将collectionView.layoutIfNeeded()
替换为flowLayout.invalidateLayout()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print("\(view.bounds.width) x \(view.bounds.height)")
let boundsSize = CGSize(width: Int(view.bounds.width), height: Int(view.bounds.height))
let flowLayout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
if flowLayout.itemSize != boundsSize {
flowLayout.itemSize = boundsSize
debugPrint("Called")
flowLayout.invalidateLayout()
}
}
答案 3 :(得分:0)
您可以将collectionView(_:layout:sizeForItemAt:)
与viewDidLayoutSubviews
一起使用。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print("\(view.bounds.width) x \(view.bounds.height)")
let boundsSize = CGSize(width: Int(view.bounds.width), height: Int(view.bounds.height))
if !boundsSize.equalTo(self. collectionViewItemSize) {
collectionView.invalidateLayout()
}
}
var collectionViewItemSize:CGSize = .zero
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
self.collectionViewItemSize = CGSize(width: Int(view.bounds.width), height: Int(view.bounds.height));
return self.collectiViewItemSize;
}
答案 4 :(得分:0)
我最终更改了itemSize
中的viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
并将大小传递给了一个方法,该方法将根据视图的未来大小进行数学运算。