iOS UICollectionView - 默认流,从右到左填充行 [英] iOS UICollectionView - default flow, fill rows from right to left

查看:14
本文介绍了iOS UICollectionView - 默认流,从右到左填充行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的一个应用程序 UICollectionView 中使用自定义单元格,但使用默认流程.目前,此视图连续显示 3 个单元格(所有单元格大小相同).单元格从左到右填充该行,但我需要从右到左.

I'm using in one of my apps UICollectionView, with custom cells but with default flow. Currently this view shows 3 cells in a row (all of them the same size). The cells fill the row from left to right, but I need it from right to left.

有可能吗?我需要创建自定义流布局吗?如果是这样,任何人都可以举一个简单的例子吗?

Is it possible? Do I need to create custom flow layout? If so, anyone can give a simple example?

任何帮助将不胜感激.

推荐答案

假设您只期望三个单元格,并为此集合视图使用标题视图,您将需要执行以下步骤:

Assuming you are expecting ONLY three cells, and using a header view for this collection view, you will need to perform the following steps:

覆盖 UICollectionViewFlowLayout

override UICollectionViewFlowLayout

@interface GSRightToLeftCollectionViewFlowLayout : UICollectionViewFlowLayout

(GS 代表 Groboot SmarTech :))

(GS is for Groboot SmarTech :))

.m 应该如下所示:

#import "GSRightToLeftCollectionViewFlowLayout.h"

typedef enum {
    // enum for comfortibility.
    CellXPositionLeft = 1,
    CellXpositionRight = 2,
    CellXpositionCenter = 3,
    CellXPositionNone = 4
} CellXPosition;

@interface GSRightToLeftCollectionViewFlowLayout ()

@property (nonatomic) BOOL cellFlag;
@property (nonatomic) float cellLeftX;
@property (nonatomic) float cellMiddleX;
@property (nonatomic) float cellRightX;

@end

@implementation GSRightToLeftCollectionViewFlowLayout

// when ever the bounds change, call layoutAttributesForElementsInRect:
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *allItems = [[super layoutAttributesForElementsInRect:rect] mutableCopy];

    for (UICollectionViewLayoutAttributes *attribute in allItems) {

        // when we get an item, calculate it's English writing position,
        // so that we can convert it to the Hebrew - Arabic position.
        if (!self.cellFlag) {

            [self calculateLocationsForCellsWithAttribute:attribute];

            self.cellFlag = YES;
        }

        // if it's a header, do not change it's place.
        if (attribute.representedElementKind == UICollectionElementKindSectionHeader) {

            continue;
        }

        // check where the item should be placed.
        CellXPosition position = [self attributeForPosition:attribute];

        switch (position) {
            case CellXPositionLeft:
                attribute.frame = CGRectMake(self.cellLeftX, attribute.frame.origin.y, attribute.frame.size.width, attribute.frame.size.height);
                break;
            case CellXpositionRight:
                attribute.frame = CGRectMake(self.cellRightX, attribute.frame.origin.y, attribute.frame.size.width, attribute.frame.size.height);
                break;
            case CellXpositionCenter:
                attribute.frame = CGRectMake(self.cellMiddleX, attribute.frame.origin.y, attribute.frame.size.width, attribute.frame.size.height);
                break;
            case CellXPositionNone:
                NSLog(@"warning");
                break;
        }
    }

    return allItems;
}


- (CellXPosition)attributeForPosition:(UICollectionViewLayoutAttributes *)attribute
{
    CellXPosition cellXposition = CellXPositionNone;

    // we will return an opposite answer
    if (attribute.indexPath.row % 3 == 0) {

        // if it's in the left side, move it to the right
        cellXposition = CellXpositionRight;

    } else if (attribute.indexPath.row % 3 == 1) {

        cellXposition = CellXpositionCenter;

    } else if (attribute.indexPath.row % 3) {

        // if it's in the right side, move it to the left
        cellXposition = CellXPositionLeft;
    }

    return cellXposition;
}

- (void)calculateLocationsForCellsWithAttribute:(UICollectionViewLayoutAttributes *)attribute
{
    float cellWidth = self.itemSize.width;
    float minimumX = self.sectionInset.left;
    float maximumX = self.sectionInset.right;
    float displayWidth = self.collectionView.contentSize.width - minimumX - maximumX;
    // on iOS6, displayWidth will be 0 (don't know why), so insert an if (displayWidth == 0) and set manually the size.

    self.cellLeftX = minimumX;
    float space = (displayWidth - cellWidth * 3) / 2;
    self.cellMiddleX = self.cellRightX + cellWidth + space;
    self.cellRightX = self.cellMiddleX + cellWidth + space;
}

@end

在您显示 CollectionView 的 Class 中,您需要这样做:

In the Class which you display the CollectionView, you need to do this:

如果您使用故事板:1.将collectionView布局更改为自定义(在属性检查器中)2. 将其类设置为 GSRightToLeftCollectionViewFlowLayout.3. 在 ViewDidLoad 中(或每当你执行初始化时)

if you are using storyboards: 1. change the collectionView layout to custom (in the attribute inspector) 2. set it's class to GSRightToLeftCollectionViewFlowLayout. 3. in ViewDidLoad (or whenever you perform initialization)

- (void)viewDidLoad
{
    [super viewDidLoad];

    GSRightToLeftCollectionViewFlowLayout *layout = [[GSRightToLeftCollectionViewFlowLayout alloc] init];
    layout.itemSize = CGSizeMake(98, 138); // set the item size.
    layout.minimumLineSpacing = 1; // other layout properties.
    layout.minimumInteritemSpacing = 1; // other layout properties.
    layout.headerReferenceSize = CGSizeMake(50, 18);
    layout.sectionInset = UIEdgeInsetsMake(1.0f, 0.0f, 1.0f, 0.0f);
    layout.scrollDirection = UICollectionViewScrollDirectionVertical;
    // in case you use headers / footers. this is also where you would register a Cell if you don't use storyboards.
    [self.collectionView registerClass:[GSReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView"];
    self.collectionView.collectionViewLayout = layout;
}

这篇关于iOS UICollectionView - 默认流,从右到左填充行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆