UICollectionView Tips

Most of us have used UICollectionView. It's like a swiss knife. Too complex to explore all the features it offers. I've used it on many occasions, but I still don't feel fully comfortable using it. To add up to that, I recently discovered UICollectionView features previously unknown to me. Here are some of them.

  1. Exchanging items in Collection view
    Say you want to replace item at indexPath sourceIndexPath with indexPath at destinationIndexPath and automatically scroll to the indexPath at destinationIndexPath. This can be achieved as follows
- (void)exchangeSourceIndexPath:(NSIndexPath*)sourceIndexPath withDestinationIndexPath:(NSIndexPath*)destinationIndexPath {
        [self.collectionView performBatchUpdates:^{
            [self.feeds exchangeObjectAtIndex:sourceIndexPath.row withObjectAtIndex:destinationIndexPath.row];
            [self.collectionView moveItemAtIndexPath:sourceIndexPath toIndexPath:destinationIndexPath];
        } completion:^(BOOL finished) {
            [self.collectionView scrollToItemAtIndexPath:destinationIndexPath atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
        }];
}
  1. Inserting item in Collection view
    Say you already have a UICollectionView with some items in it. Now you want to add a new item at the end of the list. (This is one example, but you can add new item to collection view at any index)
- (void)addItemsToList:(FeedModel*)feed {
        /// self.feeds is the collection of objects of type FeedModel. While adding new item, we will add it to self.feeds collection and then insert it at the end of collectionView.
        [self.feeds addObject:feed];
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.feeds.count - 1 inSection:0];
        [self.collectionView performBatchUpdates:^{
            [self.collectionView insertItemsAtIndexPaths:@[indexPath]];
    }   completion:^(BOOL finished) {
            [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
    }];
}
  1. Updating UICollectionView layout dynamically.
    Suppose you are creating UICollectionViewLayout programmatically. This will return the sizeForItemAtIndexPath based on the current mode. Two modes being,
    1. Small Size

    2. Large size
    Based on the current mode, we will return different values of sizeForItemAtIndexPath. However, as we change the layout size, we will also have to invalidate the previous layout.

Say this is where we are setting up the value of item size at index path.

//pragma mark - flowlayout 
 -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
        FeedModel *feed = self.feeds[indexPath.row];
        if (self.smallSize) {
            return CGSizeMake(50, 50);                
        } else {
            return CGSizeMake(200, 200);
        }
    }

We will now add the code which will toggle between two modes. Every time we toggle, we invalidate the flowLayout and reload the collectionView.

- (void)changeLayoutSize {
        [self.flowLayout invalidateLayout];
        self.onlyImage = !self.onlyImage;
        [self.collectionView reloadData];
}

This post will always be a WIP (Work in progress). I will keep adding new features as I discover them.