Question

I am making a UICollectionView control which would look like (fig-1) :

I have added the ability to delete cell by swiping the cells to right.

My problem case - If I delete the last cell by swiping (fig-2) , which will call the following code.

- (void)removeTheCell:(AnyObject *)obj {

    // remove the object
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:[self.allObjects indexOfObject:obj] inSection:0];

    [self.allObjects removeObjectAtIndex:indexPath.row];


    [self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
}

And then add a new cell with different color using following method (fig-4):

- (void)addNewObject:(NSNotification *)notification {

    NSDictionary *dict = notification.userInfo;
    NSArray *newObjects_a = [dict objectForKey:ALL_OBJECTS];

    NSMutableArray *indexArrays = [[NSMutableArray alloc] init];
    for (AnyObject *obj in newObjects_a) {
        [self.allObjects addObject:obj];
        [indexArrays addObject:[NSIndexPath indexPathForItem:[self.allObjects indexOfObject:obj] inSection:0]];
    }


    [self.collectionView performBatchUpdates:^{

        [self.collectionView insertItemsAtIndexPaths:indexArrays];

    } completion:nil];

}

The cell that is displayed still looks like the old deleted cell with its last state (fig-4). But i checked the data source it doesn't contain the deleted object. It contains the latest data.

(fig-5)If i change to list layout by selecting the segment control which call the following method:

- (IBAction)SwitchCellFrames:(id)sender {

    int selection = ((UISegmentedControl *)sender).selectedSegmentIndex;

    isGridView = selection == 0 ? YES : NO;

    if (isGridView) {
        [self.collectionView setCollectionViewLayout:gridFlowLayout animated:YES];
    }else {
        [self.collectionView setCollectionViewLayout:listFlowLayout animated:YES];
    }

}

layout variables are defined as :

    gridFlowLayout = [[UICollectionViewFlowLayout alloc] init];
    [gridFlowLayout setItemSize:CGSizeMake(160, 155)];
    [gridFlowLayout setMinimumInteritemSpacing:0.0f];
    [gridFlowLayout setMinimumLineSpacing:0.0f];
    [gridFlowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];


    listFlowLayout = [[UICollectionViewFlowLayout alloc] init];
    [listFlowLayout setItemSize:CGSizeMake(320, 80)];
    [listFlowLayout setMinimumInteritemSpacing:0.0f];
    [listFlowLayout setMinimumLineSpacing:0.0f];
    [listFlowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];

The collectionView now updates the new cell with the right color (fig-5/fig-6).

I tried [self.collectionView setNeedsDisplay] / [self.collectionView setNeedsLayout] / [self.collectionView reloadData]. These are not causing the UI to redraw itself.

I don't know what is causing the UICollectionView to retain the deleted view. Please Help.

enter image description here

Was it helpful?

Solution

Found a work arround that is working for me in this situation :

I was creating and updating the ui under - (void)awakeFromNib() of my customCell class. So, when the the new cell is added at the location from where a cell was earlier deleted, - (void)awakeFromNib() was not getting called again and a previous copy of cell was being returned.

Therefore, i made the ui update method public and removed it from - (void)awakeFromNib(). Calling UI update method explicitly from cellForItemAtIndexPath solved the problem for me.

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

    CustomViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CollectionCell" forIndexPath:indexPath];

    cell.obj = [self.allObjects objectAtIndex:indexPath.row];
    [cell handleChangesForLayoutAndPosition];
    [cell updateUI];
    [cell resetScrollView];

    cell.delegate = self;

    return cell;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top