iOS UICollectionView - alur default, isi baris dari kanan ke kiri

Saya menggunakan salah satu aplikasi saya UICollectionView, dengan sel khusus tetapi dengan aliran default. Saat ini tampilan ini menampilkan 3 sel berturut-turut (semuanya berukuran sama). Sel mengisi baris dari kiri ke kanan, tapi saya membutuhkannya dari kanan ke kiri.

Apa itu mungkin? Apakah saya perlu membuat tata letak alur khusus? Jika ya, adakah yang bisa memberikan contoh sederhana?

Bantuan apa pun akan dihargai.


person Asaf    schedule 31.10.2013    source sumber


Jawaban (2)


Dengan asumsi Anda HANYA mengharapkan tiga sel, dan menggunakan tampilan header untuk tampilan koleksi ini, Anda perlu melakukan langkah-langkah berikut:

ganti UICollectionViewFlowLayout

@interface GSRightToLeftCollectionViewFlowLayout : UICollectionViewFlowLayout

(GS untuk Groboot SmartTech :))

.m akan terlihat seperti ini:

#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

Di Kelas tempat Anda menampilkan CollectionView, Anda perlu melakukan ini:

jika Anda menggunakan storyboard: 1. ubah tata letak collectionView menjadi kustom (di pemeriksa atribut) 2. setel kelasnya ke GSRightToLeftCollectionViewFlowLayout. 3. di ViewDidLoad (atau setiap kali Anda melakukan inisialisasi)

- (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
Jika saya harus menggunakan kode ini untuk jumlah sel tak terbatas yang terlalu horizontal, perubahan apa yang harus saya lakukan pada kode tersebut.. - person Leena; 19.11.2013
comment
bisakah Anda lebih spesifik @Leena? apakah collectionView bergulir secara horizontal atau vertikal? kode tidak membatasi jumlah sel/item, hanya mengubah atribut suatu item. maksud Anda Anda memiliki jumlah item yang tak terbatas dalam satu baris? bisakah Anda mengunggah representasi visual dari tampilan koleksi yang ingin Anda buat? - person Raz; 23.11.2013
comment
biarlah saya menerapkan solusi alternatif untuk tata letak, terima kasih atas jawabannya. - person Leena; 25.11.2013
comment
jawaban yang luar biasa berguna - terima kasih! satu-satunya cara saya bisa menyelesaikan masalah saya .. stackoverflow.com/questions/24916006 ... menggunakan kode contoh Anda untuk layoutAttributesForElementsInRect dan turunkan 35, demi Tuhan! :HAI - person Fattie; 23.07.2014
comment
@Leena bisakah Anda membagikan solusi alternatif Anda? - person iosMentalist; 24.11.2014

saya memiliki masalah yang sama karena terjemahan bahasa Arab.

Inilah solusi saya: Buat subkelas UICollectionViewFlowLayout dan timpa

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

Saya menggunakan arah karakter NSLocales sebagai pemicu terjemahan RTL. Jika ini adalah bahasa LTR, ia hanya mengembalikan atribut default.

Semoga bermanfaat.

- (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
Terima kasih Pak! masalah yang saya alami saat ini adalah ia tidak lagi mempertahankan satu baris, dan malah mencoba menambahkan item di baris baru. jika Anda memiliki petunjuk, itu dihargai, sementara saya meneliti sendiri masalahnya. :) Ini berguna dalam situasi di mana Anda mungkin ingin memasukkan elemen ke UICollectionview. - person Jon Madison; 01.03.2014
comment
Poin kecil, tetapi supersAttributes tidak perlu bisa diubah. - person bcattle; 06.12.2014
comment
Kalau saya pakai ini, barangnya hilang begitu saja. Apakah ada hal khusus yang perlu saya lakukan agar ini berhasil? Apakah karena pandangan saya cukup lebar untuk di-scroll? - person uliwitness; 18.10.2016