估计高度不起作用的集合视图组合布局

Collection View Compositional Layout with estimated height not working

我希望我的应用针对包括文本大小在内的每个辅助功能选项进行优化。

我根据具有组合布局的部分制作了一个 collectionView 布局。所以我需要我的单元格的高度随着它的内容而增长。我认为使用 .estimated(constant) 可以完成这项工作,但它似乎不起作用。内部约束对我来说似乎很好。

这是我正在使用的布局:

let size = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.42), heightDimension: .estimated(90))
let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(90)))
item.contentInsets = NSDirectionalEdgeInsets(top: 5.0, leading: 12.0, bottom: 5.0, trailing: 12.0)
let group = NSCollectionLayoutGroup.vertical(layoutSize: size, subitem: item, count: 1)
let section = NSCollectionLayoutSection(group: group)
section.contentInsets = NSDirectionalEdgeInsets(top: 0.0, leading: 6.0, bottom: 0.0, trailing: 0.0)
section.orthogonalScrollingBehavior = .groupPaging

当我在辅助功能设置中设置更大的文本大小时,会发生以下情况:

单元格应该包含 2 个标签,这里是 autoLayoutConstraints :

    NSLayoutConstraint.activate([
        self.titleLabel.topAnchor.constraint(equalTo: self.container.topAnchor, constant: 10),
        self.titleLabel.leftAnchor.constraint(equalTo: self.container.leftAnchor, constant: 20),
        self.titleLabel.rightAnchor.constraint(equalTo: self.container.rightAnchor, constant: -20)
    ])

    NSLayoutConstraint.activate([
        self.subtitleLabel.topAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: 10),
        self.subtitleLabel.leftAnchor.constraint(equalTo: self.container.leftAnchor, constant: 20),
        self.subtitleLabel.rightAnchor.constraint(equalTo: self.container.rightAnchor, constant: -20),
        self.subtitleLabel.bottomAnchor.constraint(equalTo: self.container.bottomAnchor, constant: -10)
    ])

在此先感谢您的帮助。

不确定它是否与系统可访问性相关,但据我所知,您不能在项目上使用 .estimated().contentInsets

它有时确实有效,但不可靠。即使在尝试将插图应用于组时,我也在为这个权利而战(虽然它是项目的子类,但我认为它会起作用):(

我发现将 LayoutGroup 设置为水平而不是垂直可以解决问题。这是我的最终布局:

        let estimatedHeight = CGFloat(100)
        let layoutSize = NSCollectionLayoutSize(widthDimension: .estimated(200), heightDimension: .estimated(estimatedHeight))
        let item = NSCollectionLayoutItem(layoutSize: layoutSize)
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: layoutSize, subitem: item, count: 1)
        let section = NSCollectionLayoutSection(group: group)
        section.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
        section.interGroupSpacing = 10
        section.orthogonalScrollingBehavior = .groupPaging

希望对你有帮助^^

在 iOS13+ 上,如果您想创建单元格约束决定单元格高度的布局 - 试试这个:

private func configureCollectionView() {
    collectionView.collectionViewLayout = createLayout()
}

private func createLayout() -> UICollectionViewLayout {
    let layout = UICollectionViewCompositionalLayout {
        (sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
        let size = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(10))
        let item = NSCollectionLayoutItem(layoutSize: size)
        item.edgeSpacing = NSCollectionLayoutEdgeSpacing(leading: nil, top: NSCollectionLayoutSpacing.fixed(20), trailing: nil, bottom: NSCollectionLayoutSpacing.fixed(0))
        let group = NSCollectionLayoutGroup.vertical(layoutSize: size, subitems: [item])
        group.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 20)
        let section = NSCollectionLayoutSection(group: group)
        return section
    }
    return layout
}

确保您在单元格中的约束、拥抱和压缩阻力具有优先级 - 1000(必需),所有这些:堆栈视图、标签等。

你应该得到这样的东西:

或者如果你想水平滚动分页,只需添加:

section.orthogonalScrollingBehavior = .groupPaging

到你的部分 属性,关于布局创建,你会得到这样的东西:

尽情享受吧:)

为我解决问题的方法是为项目和组设置相同的高度尺寸

我知道问题的共享代码就是这种情况,@Que20 的解决方案肯定有帮助。但如果问题仍然存在,您可能需要检查一下。


例子

我正在尝试显示一个单元格,其中包含固定到单元格边距的单个 UIButton。该按钮的高度限制为 44 点。

最初的尝试

static func mapSection() -> NSCollectionLayoutSection {
    let itemSize = NSCollectionLayoutSize(
        widthDimension: .fractionalWidth(1),
        heightDimension: .fractionalHeight(1)) // Here: a fractional height to the item
    let item = NSCollectionLayoutItem(layoutSize: itemSize)

    let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
                                           heightDimension: .estimated(100)) // There: estimated height to the button cell
    let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])

    let section = NSCollectionLayoutSection(group: group)

    return section
}

尽管所有配置都正确,但按钮的高度限制被打破并且 "estimation" 变成了绝对值。

实施成功

static func mapSection() -> NSCollectionLayoutSection {
    /* 
     Notice that I estimate my button cell to be 500 points high
     It's way too much. But since it's an estimation and we're doing things well,
     it doesn't really matter to the end result.
    */
    let heightDimension = NSCollectionLayoutDimension.estimated(500)

    let itemSize = NSCollectionLayoutSize(
        widthDimension: .fractionalWidth(1),
        heightDimension: heightDimension)
    let item = NSCollectionLayoutItem(layoutSize: itemSize)

    let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
                                           heightDimension: heightDimension)
    let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])

    let section = NSCollectionLayoutSection(group: group)

    return section
}

唯一真正的区别在于项目和组都设置为相同的估计高度尺寸。但它现在有效了!