UICollectionViewCell 具有 2 列网格和动态高度

Posted

技术标签:

【中文标题】UICollectionViewCell 具有 2 列网格和动态高度【英文标题】:UICollectionViewCell With 2 column grid and dynamic height 【发布时间】:2020-04-23 19:36:36 【问题描述】:

我正在尝试使用 2 列但动态高度的集合视图。 我使用了 Autolayout 并为 Cell 提供了所需的约束

通过这种方式,我可以计算动态高度,但它的列网格失败了。

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
       let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! MenuListCollectionViewCell
       cell.frame.size.width = collectionView.frame.width/2
    cell.menuList = self.menuList[indexPath.row]
    let resizing = cell.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize, withHorizontalFittingPriority: UILayoutPriority.required, verticalFittingPriority: UILayoutPriority.fittingSizeLevel)
       return resizing

这就是我想要的样子

【问题讨论】:

我猜你需要的是交错布局。检查这个是否有帮助。 ***.com/q/32398232/5923606. 【参考方案1】:

不确定“它的列网格失败”是什么意思。

无论如何,您需要编写自定义集合视图布局。默认的 (UICollectionViewFlowLayout) 允许您通过提供sizeForItemAt 来更改单元格的高度,但这不会改变总是将单元格排列在相同高度的行中的布局行为(最高单元格的高度)。

如果我理解正确,您只需要 this raywenderlich tutorial 的相同布局。

基本上:

    创建一个UICollectionViewLayout 的子类来实现它的方法: collectionViewContentSize:返回集合视图内容的宽高 prepare: 你可以在这里计算单元格的大小和 收藏查看内容 layoutAttributesForElements: 你在哪里 返回给定数组中的UICollectionViewLayoutAttributes 纠正 layoutAttributesForItem:你在哪里返回同一种 属性,这次是针对某个项目的 将此类的对象分配给集合视图布局属性

【讨论】:

我已经尝试了 Raywenderlich 的教程,它给了我 2 个列单元格,这是你所期望的,但在这种情况下动态高度会失败。用我期望的行为截图更新了问题。请检查。 你一直说它失败了,但我真的不明白你的意思是什么。如果你能解释一下,也许我可以帮忙。无论如何,我看不到您的屏幕截图中的动态内容。所有的细胞看起来几乎一样的高度......还是我错过了什么? PS:如果您将当前状态与您想要实现的目标进行比较,这可能会很有用。 在 prepare() 中如何计算实际单元格的高度? 你使用的方法是根据约束计算大小的方法 正如我所说,yourView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height 应该给你正确的高度,如果你在视图上设置正确的约束。【参考方案2】:

你可以用这个

此代码以某种方式编写,您可以更改部分 inset 或 minimumInteritemSpacing 并使用此参数计算和调整大小

您可以使用此代码或从Github下载项目

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 

        let numberofItem: CGFloat = 2

        let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout

        let collectionViewWidth = self.collectionView.bounds.width

        let extraSpace = (numberofItem - 1) * flowLayout.minimumInteritemSpacing

        let inset = flowLayout.sectionInset.right + flowLayout.sectionInset.left

        let width = Int((collectionViewWidth - extraSpace - inset) / numberofItem)

        return CGSize(width: width, height: width)
    

【讨论】:

【参考方案3】:

通过执行以下操作,我能够达到您想要的结果。

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    return 20

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    return CGSize(width: (self.view.frame.size.width/2 - 5), height: 100)


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = customCollectionView.dequeueReusableCell(withReuseIdentifier: "test", for: indexPath)

    cell.layer.backgroundColor = UIColor.red.cgColor

    return cell

确保你已经实现了所有正确的委托

UICollectionViewDelegate UICollectionView 数据源 UICollectionViewDelegateFlowLayout

您在哪里看到高度:按照您在问题中指定的方式将其设为您自己想要的高度。

关键:确保在情节提要中将集合视图的 estimate size 设置为 NONE -> 否则代码将无法按预期工作

【讨论】:

以上是关于UICollectionViewCell 具有 2 列网格和动态高度的主要内容,如果未能解决你的问题,请参考以下文章

具有可变图像大小和自动布局的 UICollectionViewCell

UICollectionViewCell:如何让每个单元格具有不同的命名

具有动态大小单元格间距问题的 UICollectionViewCell

加载具有与其 UICollectionView 不同的 alpha 值的 UICollectionViewCell

具有自动布局的全屏 UICollectionViewCell

具有动态高度的 UICollectionViewCell 使用 NSURL 进行图像下载