【问题标题】:UICollectionViewCompositionalLayout update cell heightUICollectionViewCompositionalLayout 更新单元格高度
【发布时间】:2020-09-24 10:26:19
【问题描述】:

我有以下设置:

  • 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 时,为什么它没有被重置/删除?

【问题讨论】:

    标签: uicollectionview autolayout uicollectionviewcell ios13 uicollectionviewcompositionallayout


    【解决方案1】:

    我对此进行了更多思考,最终一起消除了高度限制。我想,如果我遵循自定尺寸单元格的理念,那么我不需要任何高度限制,但高度应该由对单元格内容的正确定义的限制来确定。

    所以我再次检查了我的单元格,我发现了一个问题,即某些内容被添加到单元格本身,而不是 contentView。在修复它并删除高度限制后,我改变了这个:

    snapshot?.reloadItems([cellIdentifier])
    

    进入这个:

    self?.collectionView.collectionViewLayout.invalidateLayout()
    

    一切都开始正常工作了。

    【讨论】:

      【解决方案2】:

      我发现最好在单独的 xib 文件中设计单元格。在该文件中,将最顶部的“Cell”元素的 Size inspector > Layout 设置为“Inferred (Constraints)”。这应该会删除与您设置的约束冲突的自动调整掩码。

      如果没问题,那么可能是布局自己创建了自动调整大小的掩码,您可以使布局无效,以便它根据单元格的所需大小重新创建自动调整大小的掩码。

      【讨论】:

      • 感谢您提出使布局无效的想法,这使我找到了解决问题的正确方法。