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

ios - UICollectionView/FlowLayout-LMLPHP

我确实设法创建了两列,但是在“布局”中寻找正确的设置以使正确的列偏移一个单元格高度的一半是很困难的。请注意,所有单元格都具有基于屏幕宽度(减去间距)的相同计算尺寸...

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

任何帮助都将不胜感激

最佳答案

这是我实现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 }

关于ios - UICollectionView/FlowLayout,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40854396/

10-13 04:27