Paul Warkentin
Paul Warkentin

Reputation: 3899

UICollectionView reloadData changes cell order

I'm using UICollectionView in one of my projects and when I try to call reloadData on the collection view, the cell order is always changed the same.
I create the cells something like that:

- (UICollectionViewCell *)collectionView:(UICollectionView *)aCollectionView 
                  cellForItemAtIndexPath:(NSIndexPath *)aIndexPath {
    PPhotoCVCell *cell = 
     [self._collectionView dequeueReusableCellWithReuseIdentifier:@"PPhotoCVCell" 
                                                     forIndexPath:aIndexPath];
    if (cell.photo == nil) {
        PPhoto *photo = self._photos[aIndexPath.row];
        cell.photo = photo;
    }

    cell.enableEditing = self._editing;
    cell.layer.shouldRasterize = YES;
    cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

    return cell;
}

The cell has two subviews of the class UIImageView, one for the image and another for an overlay if the cell is selected by the user.
When I'm in editing mode, the user can select cells. When some cells are selected and the user quits the editing mode, I set the alpha value of the overlay image view with an animation to 0.0 in the overwritten setSelected: method.
The problem is when I call the reloadData method on the collection view, the overlay image views in the selected cells hide without animation, but in other cells overlay image views appear without animation and disappear with the correct animation.
I detected that the image view for the photo is also changing when I call reloadData.

Is there any solution for this problem?

Upvotes: 2

Views: 2572

Answers (2)

brian
brian

Reputation: 53

I ran into this same issue where each time I performed reloadData, the collection view would reverse it's order. Since I didn't see an answer here after 5 years, I'm posting my solution in case anyone else runs into this.

You actually have 2 options:

  1. If you only need to reload a single cell, use the following instead of reloadData:
NSArray *thisItem = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:thisRow inSection:0]];
[self.collectionView reloadItemsAtIndexPaths:thisItem];
  1. If you need to reload all data, use the following:
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];

There's probably a reasonable explanation for this behavior somewhere, but I can't find one.

Upvotes: 4

Christopher Pickslay
Christopher Pickslay

Reputation: 17772

It sounds like your cells are being recycled. In your cell's prepareForReuse, make sure you're removing the overlay. Then add the overlay as appropriate in collectionView: cellForItemAtIndexPath:.

Upvotes: 2

Related Questions