UICollectionViewCompositionalLayout更新单元格高度

时间:2020-09-24 10:26:19

标签: uicollectionview autolayout uicollectionviewcell ios13 uicollectionviewcompositionallayout

我有以下设置:

  • 具有自定义单元格的UICollectionView,其高度由其内容定义

  • UICollectionViewCompositionalLayout定义了此类项目的尺寸

    let cellHeight: CGFloat = 260 
    let heightDimension = NSCollectionLayoutDimension.estimated(cellHeight)
    let fractionalWidth: CGFloat = 1.0
    let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(fractionalWidth),
                                         heightDimension: heightDimension)
    let item = NSCollectionLayoutItem(layoutSize: itemSize)
    
    let groupWidth = NSCollectionLayoutDimension.fractionalWidth(1.0)
    let groupSize = NSCollectionLayoutSize(widthDimension: groupWidth,
                                          heightDimension: heightDimension)
    let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                     subitems: [item])
    

这很好,直到我要更新其中一个单元格的高度。我收到以下警告:

   [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it. 
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)

"<NSAutoresizingMaskLayoutConstraint:0x6000013bdfe0 h=--& v=--& UIView:0x7fd64017a040.height == 125   (active)>",
"<NSLayoutConstraint:0x6000013b3b60 'MyCell.contentView.heightAnchor' UIView:0x7fd64017a040.height == 231   (active)>"

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000013b3b60 'MyCell.contentView.heightAnchor' UIView:0x7fd64017a040.height == 231   (active)>

单元格的原始高度确实由占位符大小定义125,但是当更新通过网络进行时,我正在像这样的单元格contentView上创建高度限制:

cell.heightConstraint = cell.contentView.heightAnchor.constraint(equalToConstant: size.height)
cell.heightConstraint.identifier = "MyCell.contentView.heightAnchor"
cell.heightConstraint.isActive = true
snapshot?.reloadItems([cellIdentifier])

size.height是新的高度。所以,问题是,我在这里想念什么?我假设NSAutoresizingMaskLayoutConstraint是由自动布局从单元格的原始高度创建的,但是当我将高度约束添加到单元格contentView时为什么不重置/删除它呢?

2 个答案:

答案 0 :(得分:1)

我对此进行了更多思考,最终我一起取消了高度限制。我认为,如果我遵循自定义单元格的哲学,那么我就不需要任何高度限制,但是高度应该由对单元格内容的适当定义的限制来确定。

因此,我再次检查了单元格,发现一个问题,有些内容是添加到单元格本身的,而不是contentView。修复并删除高度限制后,我对此进行了更改:

snapshot?.reloadItems([cellIdentifier])

对此:

self?.collectionView.collectionViewLayout.invalidateLayout()

一切都开始正常工作。

答案 1 :(得分:0)

我发现最好在单独的xib文件中设计单元。在该文件中,将最上方的“单元格”元素的大小检查器>布局设置为“推断(约束)”。那应该删除与您设置的约束冲突的自动调整大小掩码。

如果这很好,则可能是布局正在创建该自动调整大小的遮罩本身,并且您可以使布局无效,以便它根据单元格的所需大小来重新创建自动调整大小的遮罩。