4

I'm building an UICollectionView with a custom layout.

The layout is 3x4 with horizontal scrolling. I got the layout of the cells and the page scrolling working just fine.

My expected result is something like this:

enter image description here

(available at http://www.tinyuploads.com/images/0EVQnT.png)

However, when scrolling it seems the wrongs cells are being dequeued, and instead my actual result is this:

enter image description here

(available at http://www.tinyuploads.com/images/8lvJId.png)

Furthermore, when I scroll back to first page "A" is no longer in the first position.

My datasource and delegate methods looks like this:

#pragma mark - UIViewController Life Cycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.collectionView.backgroundColor = [UIColor colorWithWhite:0.25f alpha:1.0f];
    self.alphabet = [NSMutableArray arrayWithObjects:@"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I", @"J", @"K", @"L", @"M", @"N", @"O", @"P", @"Q", @"R", @"S", @"T", @"U", @"V", @"X", @"Y", @"Z", nil];
    self.colors = [NSMutableArray arrayWithObjects:[UIColor colorWithRed:(135/255.0) green:(175/255.0) blue:(88/255.0) alpha:1], [UIColor colorWithRed:(65/255.0) green:(124/255.0) blue:(185/255.0) alpha:1], [UIColor colorWithRed:(201/255.0) green:(189/255.0) blue:(64/255.0) alpha:1],  nil];

    [self.collectionView reloadData];
}


#pragma mark - UICollectionView datasource

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{

    return self.alphabet.count;

}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    NSString *title = [self.alphabet objectAtIndex:indexPath.row];
    UIColor *backgroundColor = [self.colors objectAtIndex:indexPath.row % 3];

    CategoryCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CategoryCellIdentifier forIndexPath:indexPath];

    cell.title.text = title;
    cell.backgroundColor = backgroundColor;
    [cell setNeedsLayout];

    return cell;

}

#pragma mark - UICollectionViewDelegate

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{

    NSLog(@"You touched: %d", indexPath.row);
}

I'm in doubt of as how I should be thinking of sections. As you see here I have just one section containing all my items (contents of the alphabet).

Any help is highly appreciated.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
James Fox
  • 41
  • 1
  • 2
  • Can you post your custom layout code ? – Yaman Jan 06 '13 at 15:45
  • 1
    I too am interested in your question. Are you subclassing UICollectionViewFlowLayout? Are you using Autolayout or the old spring and struts? I found NOT using both of these meant that things worked but of course those are needed. Also you are using your own UICollectionViewCell class. Put in this method (void)prepareForReuse; in your cell class, you can then inspect the cell that is about to be reused. This might give you more insight into things. – darbid Jan 07 '13 at 07:27
  • This is call Scrolling Problem,refer:http://stackoverflow.com/questions/14287353/error-setting-text-in-collection-view-cell/14289862#14289862 – LE SANG Jan 26 '13 at 10:57
  • I would suggest make it n=round(items/12) sections, so that it will be easy to do and get the workflow right. And for your requirement you don't need to subclass custom layout, you just go ahead with UICollectionViewFlowLayout. – Jirune Jan 26 '13 at 19:33
  • @James Fox please provide the solution if you got i am facing the same difficulty. – iPhone Programmatically May 21 '13 at 07:58

1 Answers1

0

WFrom what I can tell it looks like the subclass may not have been implemented correctly. Here is an example using the built in Horizontal Flow Layout that you can use to modify your code.

Note: This example assumes you have setup the correct size in the storyboard and you will have 3 columns by 4 rows.

@interface ViewController ()
@property (nonatomic, strong) NSMutableArray* alphabet;
@property (nonatomic, strong) NSMutableArray* colors;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.collectionView.backgroundColor = [UIColor colorWithWhite:0.25f alpha:1.0f];
    self.alphabet = [NSMutableArray arrayWithObjects:@"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I", @"J", @"K", @"L", @"M", @"N", @"O", @"P", @"Q", @"R", @"S", @"T", @"U", @"V", @"W", @"X", @"Y", @"Z", nil];
    self.colors = [NSMutableArray arrayWithObjects:[UIColor colorWithRed:(135/255.0) green:(175/255.0) blue:(88/255.0) alpha:1], [UIColor colorWithRed:(65/255.0) green:(124/255.0) blue:(185/255.0) alpha:1], [UIColor colorWithRed:(201/255.0) green:(189/255.0) blue:(64/255.0) alpha:1],  nil];

    [self.collectionView reloadData];
}
#pragma mark - UICollectionView datasource

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    // Full pages
    NSInteger count = self.alphabet.count /12 + (self.alphabet.count % 12 > 0 ? 1 : 0);
    count *= 12;
    return count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{


    NSInteger row = indexPath.row % 4;
    NSInteger col = indexPath.row / 4;
    NSInteger page = col /3 * 12;
    col = col % 3;
    NSInteger ii = row*3+col + page;

    NSString *title = ii >= self.alphabet.count ? nil : [self.alphabet objectAtIndex:ii];
    UIColor *backgroundColor = [self.colors objectAtIndex:col];

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
    UILabel* label = (UILabel*)[cell viewWithTag:1]; // label added in storyboard
    label.text = title;
    cell.backgroundColor = backgroundColor;
    [cell setNeedsLayout];
    cell.hidden = title == nil;
    return cell;

}

#pragma mark - UICollectionViewDelegate

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{

    NSLog(@"You touched: %d", indexPath.row);
}
@end
datinc
  • 3,404
  • 3
  • 24
  • 33