1. ホーム
  2. ios

[解決済み] UICollectionViewのセルを左揃えにする

2022-09-12 06:23:43

質問

プロジェクトでUICollectionViewを使っていますが、1行に複数の異なる幅のセルがあります。によると https://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/UsingtheFlowLayout/UsingtheFlowLayout.html

のようにすると、セルが行をまたいで同じパディングで広がります。これは、私がそれらを左揃えにして、パディング幅をハードコードしたいことを除いて、期待どおりに起こります。

私はUICollectionViewFlowLayoutをサブクラス化する必要があると思いますが、オンラインのチュートリアルなどをいくつか読んだ後、これがどのように動作するのかを理解できないようです。

どのように解決するのですか?

このスレッドにある他の解決策は、行が1つの項目で構成されている場合や、複雑すぎる場合には、正しく動作しません。

Ryan によって与えられた例に基づいて、新しい要素の Y 位置を検査することによって新しい行を検出するようにコードを変更しました。非常にシンプルで、パフォーマンスも速いです。

Swift。

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 を呼び出します。

guard layoutAttribute.representedElementCategory == .cell else {
    return
}

Objective-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;
}