1

UICollectionViewFlowLayoutは素晴らしいですが、scrollDirectionがレイアウトの方向と異なるように少し調整したいと思います。私が欲しいのは、スプリングボードのホーム画面や左/右にスワイプできる絵文字キーボードですが、セルは左から右、上から下に配置されています(上から下ではなく、左から右に配置されています)。 scrollDirectionをhorizo​​ntalに設定したUICollectionViewFlowLayoutを使用)。FlowLayoutを簡単にサブクラス化してこの変更を行う方法を知っている人はいますか?UICollectionViewFlowLayoutオブジェクトのscrollDirectionに加えてlayoutDirectionがないことに失望しています:(

@rdelmar私はあなたのソリューションに似たものを実装しましたが、それは機能します(私が望むほどエレガントではありません)が、再描画しない限りコレクションからアイテムが消えることがあることに気付きました。そのため、答えを受け入れませんでした。これが私が最終的に得たものです:

@interface UICollectionViewPagedFlowLayout : UICollectionViewFlowLayout
@property int width;
@property int height;
@end
@implementation UICollectionViewPagedFlowLayout
#warning MINOR BUG: sometimes symbols disappear
- (CGSize)collectionViewContentSize {
    CGSize size = [super collectionViewContentSize];
    // make sure it's wide enough to cover all the objects
    size.width = self.collectionView.bounds.size.width * [self.collectionView numberOfSections];
    return size;
}
- (NSArray*) layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    CGRect visibleRect;
    visibleRect.origin = self.collectionView.contentOffset;
    visibleRect.size = self.collectionView.bounds.size;

    for (UICollectionViewLayoutAttributes* attributes in array) {
        if (CGRectIntersectsRect(attributes.frame, rect)) {
            // see which section this is in
            CGRect configurableRect = UIEdgeInsetsInsetRect(visibleRect, self.sectionInset);
            int horizontalIndex = attributes.indexPath.row % self.width;
            int verticalIndex = attributes.indexPath.row / self.width;
            double xspace = (configurableRect.size.width - self.width * self.itemSize.width) / self.width;
            double yspace = (configurableRect.size.height - self.height * self.itemSize.height) / self.height;
            attributes.center = CGPointMake(attributes.indexPath.section * visibleRect.size.width + self.sectionInset.left + (self.itemSize.width + xspace) * horizontalIndex + self.itemSize.width / 2, self.sectionInset.top + (self.itemSize.height + yspace) * verticalIndex + self.itemSize.height / 2);
        }
    }
    return array;
}
@end
4

3 に答える 3

1

簡単にはわかりませんが、あなたの定義によると思います。探しているものに近いレイアウトのプロジェクトを作りました。これにより、行が水平方向、左から右、上から下に配置されます。私のデータソースは配列の配列で、各サブ配列が1行のデータを提供していました。

#import "SimpleHorizontalLayout.h" // subclass of UICollectionViewFlowLayout
#define kItemSize 60

@implementation SimpleHorizontalLayout 


-(CGSize)collectionViewContentSize {
    NSInteger xSize = [self.collectionView numberOfItemsInSection:0] * (kItemSize + 20); // the 20 is for spacing between cells.
    NSInteger ySize = [self.collectionView numberOfSections] * (kItemSize + 20);
    return CGSizeMake(xSize, ySize);
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path {
    UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path];
    attributes.size = CGSizeMake(kItemSize,kItemSize);
    NSInteger xValue = kItemSize/2 + path.row * (kItemSize +20) ;
    NSInteger yValue = kItemSize + path.section * (kItemSize +20);
    attributes.center = CGPointMake(xValue, yValue);
    return attributes;
}


-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect {
    NSInteger minRow =  (rect.origin.x > 0)?  rect.origin.x/(kItemSize +20) : 0; // need to check because bounce gives negative values for x.
    NSInteger maxRow = rect.size.width/(kItemSize +20) + minRow;
    NSMutableArray* attributes = [NSMutableArray array];
    for(NSInteger i=0 ; i < self.collectionView.numberOfSections; i++) {
        for (NSInteger j=minRow ; j < maxRow; j++) {
            NSIndexPath* indexPath = [NSIndexPath indexPathForItem:j inSection:i];
            [attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
        }
    }
    return attributes;
}
于 2012-12-28T23:17:37.210 に答える
1

IIRC、まさにこれはUICollectionViewのWWDC2012セッションで示されています。

于 2012-12-28T23:16:22.203 に答える
0

Appleがフローレイアウトのレイアウトの向きを変更するための単純なフラグを追加するまで、私はサブクラス化することになりました。いくつかのものは私の実装に固有のものですが、それは他の誰かを助けるかもしれません:

@interface UICollectionViewPagedFlowLayout : UICollectionViewFlowLayout
@property int width;
@property int height;
@end
@implementation UICollectionViewPagedFlowLayout
#warning MINOR BUG: sometimes items disappear
- (CGSize)collectionViewContentSize {
    CGSize size = [super collectionViewContentSize];
    size.width = self.collectionView.bounds.size.width * [self.collectionView numberOfSections];
    return size;
}
- (NSArray*) layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    CGRect visibleRect;
    visibleRect.origin = self.collectionView.contentOffset;
    visibleRect.size = self.collectionView.bounds.size;

    for (UICollectionViewLayoutAttributes* attributes in array) {
        if (CGRectIntersectsRect(attributes.frame, rect)) {
            // see which section this is in
            CGRect configurableRect = UIEdgeInsetsInsetRect(visibleRect, self.sectionInset);
            int horizontalIndex = attributes.indexPath.row % self.width;
            int verticalIndex = attributes.indexPath.row / self.width;
            double xspace = (configurableRect.size.width - self.width * self.itemSize.width) / self.width;
            double yspace = (configurableRect.size.height - self.height * self.itemSize.height) / self.height;
            attributes.center = CGPointMake(attributes.indexPath.section * visibleRect.size.width + self.sectionInset.left + (self.itemSize.width + xspace) * horizontalIndex + self.itemSize.width / 2, self.sectionInset.top + (self.itemSize.height + yspace) * verticalIndex + self.itemSize.height / 2);
        }
    }
    return array;
}
@end
于 2013-01-02T21:40:27.833 に答える