Swift 3:如何在UICollectionView中仅使用一个部分水平居中最后一行单元格? [英] Swift 3: How to center horizontally the last row of cells in a UICollectionView with only one section?
问题描述
我只使用一个 UICollectionView
。这是一些可视化:
I'm using a UICollectionView
with only one section. Here's some visualization:
[ x x x ]
[ x x x ]
[ x x ]
如果 UICollectionView
中的最后一行没有全部3个单元格填写,我想像这样中心那些单元格:
If the last row in the UICollectionView
does not have all 3 cells filled, I'd like to center those cells like so:
[ x x x ]
[ x x x ]
[ x x ]
我试图从以下地方实施解决方案:
I've tried to implement solutions from the following places:
然而,解决方案移动所有单元格,如果最后一行不包含X个单元格,我只想移动最后一行,因为我只有一个部分。
However, the solutions shifts all the cells, and I'd like to only shift the LAST row if that last row doesn't contain X number of cells since I only have one section.
我知道如何设置插入,但我不知道如何通过只有一个部分并尝试调整最后一行单元格的插入来实现这一点。
I know how to set insets, but I don't know how to achieve this with being only one section and trying to adjust the inset on the last row of cells.
我刚刚开始使用 UICollectionView
并且不确定如何解决这个问题?
I just started using UICollectionView
and not sure how to go around this issue?
推荐答案
听起来像您需要一些流程布局提供的所有内容以及一些自定义。子类化流程布局和覆盖 layoutAttributesForElements
应该完成这项工作:
Sounds like you need everything a flow layout offers with a little customizations. Subclassing flow layout and overriding layoutAttributesForElements
should do the job:
快速而脏的实现基本上会要求FlowLayout做给定rect的布局,然后找出最后一行中出现的项目。如果少于3个项目,则将它们均匀分开。
A quick and dirty implementation will basically ask FlowLayout to do the layout for a given rect, then figure out what items appear in the last row. If there are less than 3 items, then space them out evenly.
class LastRowCenteredLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard var elementAttributes = super.layoutAttributesForElements(in: rect) else { return nil }
guard elementAttributes.count > 0 else { return elementAttributes }
elementAttributes = elementAttributes.map { $0.copy() as! UICollectionViewLayoutAttributes }
let minY = elementAttributes.last!.frame.minY
let lastRowAttrs = elementAttributes.reversed().filter { $0.frame.minY == minY }
guard lastRowAttrs.count < 3,
let first = elementAttributes.first,
let last = elementAttributes.last else {
return elementAttributes
}
let horizontalPadding = rect.width - first.frame.minX - last.frame.maxX
let horizontalShift = horizontalPadding / 2.0
for attrs in lastRowAttrs {
attrs.frame = attrs.frame.offsetBy(dx: horizontalShift, dy: 0)
}
return elementAttributes
}
}
请注意,如果您计划动画插入/删除,您还应该覆盖 layoutAttributesForCellWithIndexPath:
并确保它返回一致的结果。
Note that if you plan on animating insertions/deletions, you should also override layoutAttributesForCellWithIndexPath:
and ensure it returns consistent results.
Apple有指南,带有dedi部分cated to subclassing。
Apple has a guide on FlowLayout with a section dedicated to subclassing.
Sample Playground:
Sample Playground:
https://gist.github.com/AnuragMishra/0a694dfa9be1a5eab9fc7368b69812ad
这篇关于Swift 3:如何在UICollectionView中仅使用一个部分水平居中最后一行单元格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!