iOS UICollectionView — поток по умолчанию, заполнение строк справа налево

Я использую в одном из своих приложений UICollectionView с пользовательскими ячейками, но с потоком по умолчанию. В настоящее время в этом представлении отображаются 3 ячейки подряд (все они одного размера). Ячейки заполняют строку слева направо, но мне нужно справа налево.

Является ли это возможным? Нужно ли мне создавать собственный макет потока? Если да, то кто-нибудь может привести простой пример?

Любая помощь будет оценена.


person Asaf    schedule 31.10.2013    source источник


Ответы (2)


Предполагая, что вы ожидаете ТОЛЬКО три ячейки и используете представление заголовка для этого представления коллекции, вам нужно будет выполнить следующие шаги:

переопределить UICollectionViewFlowLayout

@interface GSRightToLeftCollectionViewFlowLayout : UICollectionViewFlowLayout

(GS для 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, вам нужно сделать это:

если вы используете раскадровки: 1. измените макет collectionView на пользовательский (в инспекторе атрибутов) 2. установите его класс на GSRightToLeftCollectionViewFlowLayout. 3. в ViewDidLoad (или всякий раз, когда вы выполняете инициализацию)

- (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;
}
person Raz    schedule 12.11.2013
comment
Если мне нужно использовать этот код для бесконечного количества ячеек, которые слишком горизонтальны, какие изменения я должен сделать в коде. - person Leena; 19.11.2013
comment
Вы можете быть более конкретным @Leena? прокручивается collectionView горизонтально или вертикально? код не ограничивает количество ячеек/элементов, он только изменяет атрибуты элемента. Вы имеете в виду, что у вас есть бесконечное количество элементов в одной строке? не могли бы вы загрузить визуальное представление представления коллекции, которое вы хотите создать? - person Raz; 23.11.2013
comment
допустим, я применил альтернативное решение для макета, спасибо за ответ. - person Leena; 25.11.2013
comment
удивительно полезный ответ - спасибо! единственный способ решить мою проблему.. stackoverflow.com/questions/24916006... использовал ваш пример кода для layoutAttributesForElementsInRect и сдвинув его на 35, ради всего святого! :О - person Fattie; 23.07.2014
comment
@Leena, не могли бы вы поделиться своим альтернативным решением? - person iosMentalist; 24.11.2014

у меня была такая же проблема из-за арабского перевода.

Вот мое решение: создайте подкласс UICollectionViewFlowLayout и перезапишите

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect:

Я использовал направление символа NSLocales в качестве триггера для перевода RTL. Если это язык LTR, он просто возвращает атрибуты по умолчанию.

Надеюсь, это полезно.

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray *supersAttributes = [super layoutAttributesForElementsInRect:rect];
    NSLocale *currentLocale = ((NSLocale *) [NSLocale currentLocale]);
    NSLocaleLanguageDirection direction = [NSLocale characterDirectionForLanguage:currentLocale.localeIdentifier];

    // if it's an RTL language: change the frame
    if (direction == NSLocaleLanguageDirectionRightToLeft) {
        for (UICollectionViewLayoutAttributes *attributes in supersAttributes) {
            CGRect frame = attributes.frame;
            frame.origin.x = rect.size.width - attributes.frame.size.width - attributes.frame.origin.x;
            attributes.frame = frame;
        }
    }
    return supersAttributes;
}
person Community    schedule 27.12.2013
comment
Спасибо, сэр! проблема, с которой я сейчас сталкиваюсь, заключается в том, что она больше не сохраняет одну строку и вместо этого пытается добавить элементы в новую строку. если у вас есть какие-либо указатели, они приветствуются, пока я сам изучаю проблему. :) Это полезно в ситуации, когда вы можете захотеть поместить элементы в UICollectionview. - person Jon Madison; 01.03.2014
comment
Незначительное замечание, но supersAttributes не обязательно должно быть изменчивым. - person bcattle; 06.12.2014
comment
Когда я использую это, предметы просто исчезают. Есть ли что-то особенное, что мне нужно сделать, чтобы это сработало? Это потому, что мой обзор достаточно широк для прокрутки? - person uliwitness; 18.10.2016