尽管sizeForItemAt已实现,但UICollectionViewFlowLayout单元格大小永远不会更改

时间:2017-12-19 20:43:26

标签: ios swift uicollectionview uicollectionviewlayout

我的UICollectionViewCell内置UICollectionView UICollectionViewFlowLayout。我正在使单元格成为集合视图的委托和数据源。我符合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
  }
}

2 个答案:

答案 0 :(得分:5)

问题

  • 根据Apple documents for UICollectionViewFlowLayout's itemSize

      

    如果委托没有实现collectionView(_:layout:sizeForItemAt :)方法,则流布局使用此属性中的值来设置每个单元格的大小。这导致细胞都具有相同的大小。

         

    默认大小值为(50.0,50.0)。

  • 它清楚地表明itemSize仅在委托没有实现collectionView(_:layout:sizeForItemAt :)方法时使用,而没有提到itemSize会返回来自collectionView(_:layout:sizeForItemAt:)的值。它们是2个不同的值。这就是itemSizesizeForItemAt实施layout.itemSize.height后不会发生变化的原因

    因此,当collectionView使用默认值(50)时,这是有道理的。

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

  • 如果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
  • 如果collectionView(_:layout:sizeForItemAt:)每个单元格的大小不同,则需要使用UICollectionView's layoutAttributesForItem(at:) method。在IndexPath上获取UICollectionViewLayoutAttributes并使用layoutAttributes.size来计算

    layoutAttributes.size是从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)

    返回的值
    .form-check

答案 1 :(得分:0)

我认为你的注册问题...删除它并在故事板中设置单元格。只是猜测......

你有2个单元格,其中一个是为collectionView注册的?

如果您在故事板中设置单元格,则注册也可能会导致问题

  collectionView.register(SomeOtherCell.self, forCellWithReuseIdentifier: SomeOtherCell.reuseIdentifier)