gpt4 book ai didi

ios - 如何在方向更改时正确处理 UICollectionViewLayout 的 itemSize

转载 作者:行者123 更新时间:2023-11-28 06:22:51 27 4
gpt4 key购买 nike

我有一个带有自定义 UICOllectionViewLayout 的 UICollectionViewSubclass

如何最好地处理方向更改时的 itemSize 更改?

class CollectSubclass: UICollectionView {

/// When orientation changes, then invalidate the layout
open override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)

if ((traitCollection.verticalSizeClass != previousTraitCollection?.verticalSizeClass) || (traitCollection.horizontalSizeClass != previousTraitCollection?.horizontalSizeClass)) {
collectionViewLayout.invalidateLayout()
}
}
}

一旦布局因方向改变而失效,我将单元格的 size.width 计算为 UICollectionView 的 width

这在 iPhone 7 Plus 模拟器上运行良好,但在 iPhone 7、5、SE 等较小的模拟器上失败。

似乎一旦 invalidateLayout 被调用,下面的函数就会被触发

 /// Lays out subviews.
override open func layoutSubviews() {
super.layoutSubviews()
}

此函数依次调用 UICollectionViewLayout 子类上的 prepare 函数,我在其中使用 collectionView 的新框架来计算单元格的大小。

在 iPhone-7-Plus 上,traitCollectionDidChange 被触发一次。并且layoutSubviews被触发一次导致prepare被触发一次。

然而,在较小的模拟器上,traitCollectionDidChange 被触发一次,但 layoutSubviews 被触发两次。

随着 layoutSubviews 的第一个触发器,UICOllectionView 帧大小几乎应该是什么。在第二次触发时,UICOllectionView 框架大小现在是它应该的正确大小。

使用两种不同的帧尺寸被调用两次将使我准备两次布局(这是非常昂贵的)。

我在继承 UICOllectionViews 和 UICollectionViewLayouts 时遗漏了什么吗?感谢您的帮助。

如果需要我也可以提供示例工程

最佳答案

如果在您的设置中,其中一个 UICollectionViewCells 的宽度仅基于 UICollectionView 的大小以及屏幕的大小和方向(并且没有其他因素),以下是设置 Collection View 单元格大小的简洁方法:

1) 首次加载 View 时,预先计算纵向和横向单元格的大小。同时创建一个变量 currCellDimensions 来保存单元格的当前尺寸,并设置其初始值。

2) 沿这些行覆盖函数 viewWillTransitionToSize:

    override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {

super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
setCurrentCollectionCellDimensions(size) // This code executes before the rotation begins, but "size" is the size that the main view is going to be after the rotation occurs. As of iOS 8, the size of an object swaps its width and its height when the UI changes its orientation.
}

3) 实现 setCurrentCollectionCellDimensions():

    func setCurrentCollectionCellDimensions(newSize: CGSize) {

if (newSize.width < newSize.height) {
// set currCellDimensions to what it should be in portrait orientation
} else {
// set currCellDimension to what it should be in landscape orientation
}

if collectionView != nil {

collectionView.collectionViewLayout.invalidateLayout() // To trigger sizeForItemAtIndexPath to recalculate cell sizes

collectionView.reloadData() // To trigger cellForItemAtIndexPath to redraw the cells that are visible to the user. Without this call, the cell layout looks wrong on some iPhones.
}
}

4) 最后,让 sizeForItemAtIndexPath() 返回 currCellDimensions

关于ios - 如何在方向更改时正确处理 UICollectionViewLayout 的 itemSize,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42826342/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com