问题描述
我在我的项目中使用 UICollectionView,其中一条线上有多个不同宽度的单元格.根据:https://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/UsingtheFlowLayout/UsingtheFlowLayout.html
I am using a UICollectionView in my project, where there are multiple cells of differing widths on a line. According to:https://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/UsingtheFlowLayout/UsingtheFlowLayout.html
它以相等的填充将单元格散布在整条线上.这按预期发生,除了我想左对齐它们,并硬编码填充宽度.
it spreads the cells out across the line with equal padding. This happens as expected, except I want to left justify them, and hard code a padding width.
我想我需要继承 UICollectionViewFlowLayout,但是在阅读了一些在线教程等之后,我似乎不明白这是如何工作的.
I figure I need to subclass UICollectionViewFlowLayout, however after reading some of the tutorials etc online I just don't seem to get how this works.
推荐答案
当该行仅由 1 个项目组成或过于复杂时,该线程中的其他解决方案无法正常工作.
The other solutions in this thread do not work properly, when the line is composed by only 1 item or are over complicated.
根据 Ryan 给出的示例,我更改了代码以通过检查新元素的 Y 位置来检测新行.非常简单和快速的性能.
Based on the example given by Ryan, I changed the code to detect a new line by inspecting the Y position of the new element. Very simple and quick in performance.
斯威夫特:
class LeftAlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributes = super.layoutAttributesForElements(in: rect)
var leftMargin = sectionInset.left
var maxY: CGFloat = -1.0
attributes?.forEach { layoutAttribute in
if layoutAttribute.frame.origin.y >= maxY {
leftMargin = sectionInset.left
}
layoutAttribute.frame.origin.x = leftMargin
leftMargin += layoutAttribute.frame.width + minimumInteritemSpacing
maxY = max(layoutAttribute.frame.maxY , maxY)
}
return attributes
}
}
如果您想让补充视图保持其大小,请在 forEach
调用的闭包顶部添加以下内容:
If you want to have supplementary views keep their size, add the following at the top of the closure in the forEach
call:
guard layoutAttribute.representedElementCategory == .cell else {
return
}
目标-C:
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
CGFloat leftMargin = self.sectionInset.left; //initalized to silence compiler, and actaully safer, but not planning to use.
CGFloat maxY = -1.0f;
//this loop assumes attributes are in IndexPath order
for (UICollectionViewLayoutAttributes *attribute in attributes) {
if (attribute.frame.origin.y >= maxY) {
leftMargin = self.sectionInset.left;
}
attribute.frame = CGRectMake(leftMargin, attribute.frame.origin.y, attribute.frame.size.width, attribute.frame.size.height);
leftMargin += attribute.frame.size.width + self.minimumInteritemSpacing;
maxY = MAX(CGRectGetMaxY(attribute.frame), maxY);
}
return attributes;
}
这篇关于在 UICollectionView 中左对齐单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!