gpt4 book ai didi

ios - 尽管实现了 sizeForItemAt,但 UICollectionViewFlowLayout 单元格大小永远不会改变

转载 作者:搜寻专家 更新时间:2023-10-31 08:24:32 24 4
gpt4 key购买 nike

我有一个 UICollectionViewCell,里面有一个 UICollectionViewUICollectionViewFlowLayout。我正在使单元格成为 Collection View 的委托(delegate)和数据源。我符合 UICollectionViewDelegateFlowLayout 并实现 collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize(并返回正确的大小)。

但是,当我调用 layout.itemSize.height 时,我得到了默认高度 50。

class MyCell: UICollectionViewCell {
fileprivate lazy var collectionView: UICollectionView = {
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(SomeOtherCell.self, forCellWithReuseIdentifier: SomeOtherCell.reuseIdentifier)
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
return collectionView
}()

fileprivate lazy var layout: UICollectionViewFlowLayout? = {
let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
layout?.scrollDirection = .horizontal
layout?.sectionInset = UIEdgeInsets.zero
return layout
}()

override func sizeThatFits(_ size: CGSize) -> CGSize {
collectionView.frame = CGRect(x: layoutMargins.left, y: origin.y, width: width, height: layout.itemSize.height)
// layout.itemSize.height is always 50
}
}
extension MyCell: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
guard tags.count != 0 else {
return .zero
}

let tag = Tag(text: tags[indexPath.item], index: indexPath.item)
placeholderCell.configure(with: tag)
let size = placeholderCell.getFrame(at: .zero, fitting: placeholderCell.width, alignedBy: semanticContentAttribute, apply: false).size
collectionViewWidth += size.width
// this size is always correct, that's what I want when I call layout.itemSize.height
return size
}
}

最佳答案

问题

  • 根据 Apple documents for UICollectionViewFlowLayout's itemSize

    If the delegate does not implement the collectionView(_:layout:sizeForItemAt:) method, the flow layout uses the value in this property to set the size of each cell. This results in cells that all have the same size.

    The default size value is (50.0, 50.0).

  • 明确表示 itemSize 仅在委托(delegate)未实现 collectionView(_:layout:sizeForItemAt:) 方法时使用,没有文字提及 itemSize 将从 collectionView(_:layout:sizeForItemAt:) 返回值。 它们是 2 个不同的值。这就是为什么尽管实现了 sizeForItemAtitemSize 也不会改变

    因此,如果 layout.itemSize.height 在您使用时具有默认值 (50),这是有意义的。

您的问题的解决方案是什么?

  • 如果您的 collectionView 上的所有单元格都具有相同的大小,我建议为 itemSize 设置一个值并且不要实现 collectionView(_ :layout:sizeForItemAt:) 方法(删除 UICollectionViewDelegateFlowLayout 的扩展)。

    class MyCell: UICollectionViewCell {
    fileprivate lazy var collectionView: UICollectionView = {
    let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
    // collectionView.delegate = self
    collectionView.dataSource = self
    collectionView.register(SomeOtherCell.self, forCellWithReuseIdentifier: SomeOtherCell.reuseIdentifier)
    collectionView.showsHorizontalScrollIndicator = false
    collectionView.showsVerticalScrollIndicator = false
    return collectionView
    }()

    fileprivate lazy var layout: UICollectionViewFlowLayout? = {
    let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
    layout?.scrollDirection = .horizontal
    layout?.sectionInset = UIEdgeInsets.zero
    // Calculate and change |itemSize| here
    layout?.itemSize = YOUR_CELL_SIZE_AFTER_CALCULATED
    return layout
    }()

    override func sizeThatFits(_ size: CGSize) -> CGSize {
    collectionView.frame = CGRect(x: layoutMargins.left, y: origin.y, width: width, height: layout.itemSize.height)
    // layout.itemSize.height is |YOUR_CELL_SIZE_AFTER_CALCULATED.height|
    }
    }
  • 如果 collectionView 每个单元格的大小不同,您需要使用 UICollectionView's layoutAttributesForItem(at:) method .在一个IndexPath处获取UICollectionViewLayoutAttributes并使用layoutAttributes.size来计算

    layoutAttributes.size 是从 collectionView(_:layout:sizeForItemAt:)

    返回的值
    let indexPath = // IndexPath you need to use to calculate
    let layoutAttributes : UICollectionViewLayoutAttributes? = collectionView.layoutAttributesForItem(at: indexPath)
    // Use this value to calculate |collectionView| frame
    print(layoutAttributes?.size)

关于ios - 尽管实现了 sizeForItemAt,但 UICollectionViewFlowLayout 单元格大小永远不会改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47894895/

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