UICollectionView / FlowLayout

Posted

技术标签:

【中文标题】UICollectionView / FlowLayout【英文标题】: 【发布时间】:2016-11-28 22:08:02 【问题描述】:

我在使用 UICollectionView 和相关布局时遇到了挑战。我正在尝试创建一个具有两列的垂直 UICollectionView,其中左右列中的单元格的位置如图所示:

我确实可以毫无问题地创建两列,但很难在我的布局中找到正确的设置,以便使右列偏移一个单元格高度的一半。请注意,所有单元格都具有基于屏幕宽度(减去间距)的相同计算尺寸...

我的数据数组中的每个单元格都有一个位置索引,因此我可以根据它轻松找出一个单元格是位于右侧还是左侧(奇数/偶数)

非常感谢任何帮助

【问题讨论】:

我会尝试继承默认流布局,覆盖计算每个单元格框架的方法并修改返回值以具有偏移量。 @EmilioPelaez 我已经对流布局进行了子类化,但我不确定如何将顶部偏移设置为奇数单元格与偶数单元格不同。例如,它实际上只是第一个奇数单元格,它必须低于 0 索引单元格,然后所有其他单元格将再次具有相同的偏移量......希望它有意义;) 我可能看不到全貌,但就我的看法而言,右侧的所有单元格(其indexPath.item 值可能为奇数)需要偏移x。我会继承UICollectionViewFlowLayout 并覆盖layoutAttributesForItemAtIndexPath。如果indexPath.item 是偶数,则返回super,否则,调用super 并存储结果,将帧更新为x 的新矩形偏移量并返回更新后的值。 @EmilioPelaez 不确定我是否关注返回超级或呼叫超级。你可以解释或展示和sn-p展示你的意思吗?此外,我正在努力的偏移量是右列中第一个奇数项在 y 轴上的第一个偏移量 【参考方案1】:

以下是我将如何实现 UICollectionViewFlowLayout 的子类来实现您想要的。

class OffsetFlowLayout: UICollectionViewFlowLayout 
    var verticalOffset: CGFloat = 0

    override func prepare() 
        super.prepare()
        verticalOffset = 100 // Calculate offset here
    

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? 
        guard let attributes = super.layoutAttributesForItem(at: indexPath) else  return nil 
        guard remainder(Double(indexPath.row), 2) != 0 else  return attributes 
        //  For each item in the right column, offset the y value of it's origin
        attributes.frame.origin.y += verticalOffset
        return attributes
    

如您所见,在我们实现layoutAttributesForItem 时,我们要做的第一件事是调用 super 并存储它返回的值。然后我们检查索引,如果我们在左列,我们返回 super 给我们的,这将是“默认”值。

如果我们在右列,我们修改属性对象以将单元格的框架移动我们想要的偏移量,然后返回那个。

注意:我没有对此进行测试。 UICollectionViewFlowLayout 有可能使用前一个单元格来布局下一个单元格,在这种情况下,您只需修改右列中的第一个元素,只需将 guard remainder(Double(indexPath.row), 2) != 0 else return attributes 更改为 guard indexPath.row == 1 else return attributes

【讨论】:

我使用相同的方法来创建可捕捉的集合视图标题,就像一个魅力 @AlexanderTkachenko Apple 向UICollectionViewFlowLayout 添加了一个名为sectionHeadersPinToVisibleBounds 的属性;) 哇,谢谢,太棒了!)当我们放弃对 ios 8 的支持时,一定会试试这个

以上是关于UICollectionView / FlowLayout的主要内容,如果未能解决你的问题,请参考以下文章

-[UICollectionView _endItemAnimations] 中的 UICollectionView 断言失败

如何滚动另一个 UICollectionView 下方的 UICollectionView?

UICollectionView 单元内部已加载,但 UICollectionView 未显示

UICollectionView 断言失败 -[UICollectionView _updateWithItems:tentativelyForReordering:]

UITableviewCell 中的 UICollectionView。添加约束后,UICollectionView 不显示

将标题添加到 UICollectionView,而不是 UICollectionView 的部分