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.
- Exchanging items in Collection view
Say you want to replace item at indexPathsourceIndexPath
with indexPath atdestinationIndexPath
and automatically scroll to the indexPath atdestinationIndexPath
. 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];
}];
}
- Inserting item in Collection view
Say you already have aUICollectionView
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];
}];
}
- Updating
UICollectionView
layout dynamically.
Suppose you are creatingUICollectionViewLayout
programmatically. This will return thesizeForItemAtIndexPath
based on the current mode. Two modes being,
1. Small Size
2. Large size
Based on the current mode, we will return different values ofsizeForItemAtIndexPath
. 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.