本文介绍了在 UICollectionView 中左对齐单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的项目中使用 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 中左对齐单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 02:12