I have a UICollectionView. It scrolls horizontally, has only a single row of items, and behaves like a paging UIScrollView. I\'m making something along the lines of the Safari t
And here's yet another solution (targetIndexPath is the indexPath of the cell to be removed). This code can simply be placed in a removeCellAtIndexPath:(NSIndexPath*)targetIndexPath method and you're done (assuming my adaptations from my code to public code are correct, otherwise ask me and I'll try to help).
// (Here it's assumed that self.collectionView.collectionViewLayout has been assigned a UICollectionViewFlowLayout before; note the word "FLOW" in that class name)
UICollectionViewFlowLayout* layout = (UICollectionViewFlowLayout*) self.collectionView.collectionViewLayout;
// Find index path of the last cell in collection view:
NSIndexPath* lastIndexPath = [self lastItemIndexPath];
// Extend content area temporarily to fill out space left by the last row after deletion, if last row is visible:
BOOL lastRowWasVisible = NO;
if ([self.collectionView icn_cellAtIndexPathIsVisible:lastIndexPath]) {
lastRowWasVisible = YES;
// Adapt section spacing to temporarily fill out the space potentially left after removing last cell:
CGFloat cellWithLineSpacingHeight = 79.0f + 8.0f; // Height of my cell + one line spacing
layout.sectionInset = UIEdgeInsetsMake(0.0f, 0.0f, cellWithLineSpacingHeight, 0.0f);
}
// Remove the cell:
[self.collectionView performBatchUpdates:^{
[self.collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObject:targetIndexPath]];
} completion:^(BOOL finished) {
// Only scroll if we had the last row visible:
if (lastRowWasVisible) {
NSIndexPath* lastItemIndexPath = [self lastItemIndexPath];
// Run a custom scroll animation for two reasons; 1. that way we can reset the insets when animation is finished, and 2. using the "animated:YES" option lags here for some reason:
[UIView animateWithDuration:0.3f animations:^{
[self.collectionView scrollToItemAtIndexPath:prevItemIndexPath atScrollPosition:UICollectionViewScrollPositionBottom animated:NO];
} completion:^(BOOL finished) {
// Reset the space placeholder once having scrolled away from it:
layout.sectionInset = UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f);
}];
}
}];
The icn_cellAtIndexPathIsVisible: method is just a category on UICollectionView:
- (BOOL) icn_cellAtIndexPathIsVisible:(NSIndexPath*)indexPath {
BOOL __block wasVisible = NO;
[self.indexPathsForVisibleItems enumerateObjectsUsingBlock:^(NSIndexPath* ip, NSUInteger idx, BOOL *stop) {
if ([ip isEqual:indexPath]) {
wasVisible = YES;
*stop = YES;
}
}];
return wasVisible;
}
Update: This only works with one section.