尝试使用 UICollectionViewCompositionalLayout 实现固定高度、动态宽度(包裹内容)水平 UICollectionView 的单元格

Che*_*eng 0 ios uicollectionview swift

/sf/answers/3586231701/中,它展示了如何UICollectionView通过使用在 Vertical 的单元格中实现全宽度、动态高度UICollectionViewCompositionalLayout

我们希望在水平上实现同样的目标UICollectionView,但有要求

  1. 固定高度44
  2. 最小宽度 44
  3. 当内容增长时,宽度应该动态放大

我们的解决方案如下所示

class MenuTabsView: UIView, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
   
    lazy var collView: UICollectionView = {
        let itemSize = NSCollectionLayoutSize(
            widthDimension: NSCollectionLayoutDimension.estimated(44),
            heightDimension: NSCollectionLayoutDimension.fractionalHeight(1.0)
        )
        let item = NSCollectionLayoutItem(
            layoutSize: itemSize
        )
        item.contentInsets = NSDirectionalEdgeInsets(
            top: 0,
            leading: 0,
            bottom: 0,
            trailing: 1
        )
        let group = NSCollectionLayoutGroup.horizontal(
            layoutSize: itemSize,
            subitem: item,
            count: 1
        )
        let section = NSCollectionLayoutSection(group: group)
        
        let configuration = UICollectionViewCompositionalLayoutConfiguration()
        configuration.scrollDirection = .horizontal
        
        let layout = UICollectionViewCompositionalLayout(section: section, configuration: configuration)
        
        let cv = UICollectionView.init(frame: CGRect.zero, collectionViewLayout: layout)
        cv.showsHorizontalScrollIndicator = false
        cv.backgroundColor = .white
        cv.delegate = self
        cv.dataSource = self
        
        return cv
    }()
Run Code Online (Sandbox Code Playgroud)

我们期望通过使用widthDimension: NSCollectionLayoutDimension.estimated(44),这是使单元格宽度动态增长的关键。但是,这并没有按预期工作。看起来像

在此输入图像描述

我想知道,我们如何使用 来解决这个问题UICollectionViewCompositionalLayout?完整的可行项目位于https://github.com/yccheok/PageViewControllerWithTabs/tree/UICollectionViewCompositionalLayout


点/秒

我们希望避免使用UICollectionViewDelegateFlowLayout method collectionView(_:layout:sizeForItemAt:). 因为,我们的单元格可能会变得复杂,并且除了 之外,它还会包含其他视图UILabel。必须手动计算内容大小将使解决方案不灵活且容易出错。

wil*_*inn 6

我已经创造了你需要的东西。请按照以下步骤操作:

  • 创建一个内部带有标签的单元格。
  • 向标签添加尾随和前导约束(我的示例有 10 和 10)(重要)
  • 将标签设置为垂直对齐。
  • 将标签的宽度设置为 >= 44。您可以通过检查约束并将其从 equal 更改为 >= 来完成此操作。

完成此操作后,您需要创建布局。我有以下功能(我的高度为 50,在你的情况下只需更改为 44):

func layoutConfig() -> UICollectionViewCompositionalLayout {
    return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in
        let itemSize = NSCollectionLayoutSize(widthDimension: .estimated(44), heightDimension: .fractionalHeight(1))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        let groupSize = NSCollectionLayoutSize(widthDimension: .estimated(44), heightDimension: .absolute(50))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
        let section = NSCollectionLayoutSection(group: group)
        section.orthogonalScrollingBehavior = .continuous
        return section
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在 viewDidLoad() 函数中,在调用委托或 dataSource 方法之前,您需要调用以下内容(假设您保留相同的函数名称):

collectionView.collectionViewLayout = layoutConfig()
Run Code Online (Sandbox Code Playgroud)

您最终应该得到以下结果。它水平滚动: 在此输入图像描述

这是示例的源代码:

https://github.com/williamfinn/Horizo​​ntalCollectionExample

  • 我的天啊!太感谢了!我想我注意到我的问题是调用“NSCollectionLayoutGroup.horizo​​ntal(layoutSize:, subitem:, count:)”而不是“NSCollectionLayoutGroup.horizo​​ntal(layoutSize:, subitems:)”。今晚我可以睡得更香了,明天继续。多谢! (2认同)