gpt4 book ai didi

ios - UICollectionView 列的垂直偏移

转载 作者:行者123 更新时间:2023-11-28 07:57:55 24 4
gpt4 key购买 nike

右图是我想要达到的效果

enter image description here有谁知道我如何在两列 UICollectionView 上实现这一点?我可以通过测试 if (indexPath.row % 2 = 0) 来辨别我的列,但我无法设法实现这个结果。

他们这样做很简单吗?或者我需要自定义 UICollectionViewFlowLayout 吗?

注意:我所有的单元格大小都一样。

最佳答案

是的,您需要创建自定义 UICollectionViewLayout,这很容易实现。您只需要以下内容:

  1. prepare() : 执行提供布局信息所需的前期计算

  2. collectionViewContentSize : 根据您的初始计算返回整个内容区域的整体大小

  3. layoutAttributesForElements(in:) : 返回指定矩形内的单元格和 View 的属性

现在我们有了相同大小的单元格,这很容易实现。

让我们声明几个要使用的变量:

    // Adjust this as you need
fileprivate var offset: CGFloat = 50

// Properties for configuring the layout: the number of columns and the cell padding.
fileprivate var numberOfColumns = 2
fileprivate var cellPadding: CGFloat = 10

// Cache the calculated attributes. When you call prepare(), you’ll calculate the attributes for all items and add them to the cache. You can be efficient and
fileprivate var cache = [UICollectionViewLayoutAttributes]()

// Properties to store the content size.
fileprivate var contentHeight: CGFloat = 0
fileprivate var contentWidth: CGFloat {
guard let collectionView = collectionView else {
return 0
}
let insets = collectionView.contentInset
return collectionView.bounds.width - (insets.left + insets.right)
}

接下来让我们覆盖prepare()方法

    override func prepare() {
// If cache is empty and the collection view exists – calculate the layout attributes
guard cache.isEmpty == true, let collectionView = collectionView else {
return
}

// xOffset: array with the x-coordinate for every column based on the column widths
// yOffset: array with the y-position for every column, Using odd-even logic to push the even cell upwards and odd cells down.
let columnWidth = contentWidth / CGFloat(numberOfColumns)
var xOffset = [CGFloat]()
for column in 0 ..< numberOfColumns {
xOffset.append(CGFloat(column) * columnWidth)
}
var column = 0

var yOffset = [CGFloat]()
for i in 0..<numberOfColumns {
yOffset.append((i % 2 == 0) ? 0 : offset)
}

for item in 0 ..< collectionView.numberOfItems(inSection: 0) {

let indexPath = IndexPath(item: item, section: 0)

// Calculate insetFrame that can be set to the attribute
let cellHeight = columnWidth - (cellPadding * 2)
let height = cellPadding * 2 + cellHeight
let frame = CGRect(x: xOffset[column], y: yOffset[column], width: columnWidth, height: height)
let insetFrame = frame.insetBy(dx: cellPadding, dy: cellPadding)

// Create an instance of UICollectionViewLayoutAttribute, sets its frame using insetFrame and appends the attributes to cache.
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
attributes.frame = insetFrame
cache.append(attributes)

// Update the contentHeight to account for the frame of the newly calculated item. It then advances the yOffset for the current column based on the frame
contentHeight = max(contentHeight, frame.maxY)
yOffset[column] = yOffset[column] + height

column = column < (numberOfColumns - 1) ? (column + 1) : 0
}
}

最后我们需要 collectionViewContentSizelayoutAttributesForElements(in:)

    //    Using contentWidth and contentHeight from previous steps, calculate collectionViewContentSize.
override var collectionViewContentSize: CGSize {
return CGSize(width: contentWidth, height: contentHeight)
}

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

var visibleLayoutAttributes = [UICollectionViewLayoutAttributes]()

for attributes in cache {
if attributes.frame.intersects(rect) {
visibleLayoutAttributes.append(attributes)
}
}
return visibleLayoutAttributes
}

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return cache[indexPath.item]
}

你可以找到gist与类(class)。

它是这样显示的:

Demo

注意:这只是一个演示,您可能需要根据自己的需要进行调整。

希望对您有所帮助!

关于ios - UICollectionView 列的垂直偏移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47488825/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com