iOS UICollectionView - โฟลว์เริ่มต้น เติมแถวจากขวาไปซ้าย

ฉันใช้ UICollectionView ในแอปใดแอปหนึ่งของฉัน โดยมีเซลล์ที่กำหนดเอง แต่มีโฟลว์เริ่มต้น ขณะนี้มุมมองนี้แสดง 3 เซลล์ติดต่อกัน (ทุกเซลล์มีขนาดเท่ากัน) เซลล์ต่างๆ เติมแถวจากซ้ายไปขวา แต่ฉันต้องการจากขวาไปซ้าย

เป็นไปได้ไหม? ฉันจำเป็นต้องสร้างเค้าโครงโฟลว์แบบกำหนดเองหรือไม่ ถ้าเป็นเช่นนั้น ใครสามารถยกตัวอย่างง่ายๆ ได้บ้าง?

ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม.




คำตอบ (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