1

I would like to have three sections inside a UICollectionView. Each section shall display its items in the same row. If the items won't fit on the screen they should still remain in the same row and the user should scroll to right to see them all.

In a nutshell, I would like to prevent the items flow into next line. Hope it makes sense.

I have found some strange solutions as here. But these don't really work, if you have more than one section.

How can I tackle this problem? Is there a setting on Storyboard or do I have to use a custom Layout afterall?

Community
  • 1
  • 1
Houman
  • 64,245
  • 87
  • 278
  • 460

2 Answers2

0

Use multiple UICollectionViews, each with its own scrollable area.

Gaurav Sharma
  • 2,680
  • 3
  • 26
  • 36
0

I wrote this layout a while ago, but I think it should still work. The data source is an array of arrays, so each row is a new section. Here's the flow layout class,

#define space 5
#import "MultpleLineLayout.h"

@implementation MultpleLineLayout { // a subclass of UICollectionViewFlowLayout
    NSInteger itemWidth;
    NSInteger itemHeight;
}

-(id)init {
    if (self = [super init]) {
        itemWidth = 60;
        itemHeight = 60;
    }
    return self;
}

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

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


-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect {
    NSInteger minRow =  (rect.origin.x > 0)?  rect.origin.x/(itemWidth + space) : 0; // need to check because bounce gives negative values  for x.
    NSInteger maxRow = rect.size.width/(itemWidth + space) + 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;
}
rdelmar
  • 103,982
  • 12
  • 207
  • 218