Consider a standard, vertically scrollable flow layout filled with enough cells to trigger scrolling. When scrolling down, if you delete an element in such a way that the size of the contents of the collection view should be reduced to accommodate a new number of elements (i.e., delete the last element in the bottom row), the row of cells that scroll from the top are hidden. At the end of the delete animation, the top line appears without animation - this is a very unpleasant effect.
In slow motion:

It is very simple to reproduce:
Create a new project with one view and change the default value ViewControlleras a subclassUICollectionViewController
UICollectionViewController , , ViewController. "" 200x200.
ViewController.m:
@interface ViewController ()
@property(nonatomic, assign) NSInteger numberOfItems;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.numberOfItems = 19;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.numberOfItems;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
return [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
self.numberOfItems--;
[collectionView deleteItemsAtIndexPaths:@[indexPath]];
}
@end
, , , . UICollectionView, , - , . cell.hidden = NO (hidden - YES). hidden, , , , .
-initialLayoutAttributesForAppearingItemAtIndexPath , deleteItemsAtIndexPaths:, , . , , reloadData , , , , :
[collectionView deleteItemsAtIndexPaths:@[indexPath]];
[collectionView performBatchUpdates:^{
[collectionView reloadData];
} completion:nil];
, , . , , reloadData - , .
:
, , . , , layoutSubviews, (layoutAttributesForElementsInRect:) applyLayoutAttributes: .
:
// user taps cell (to delete it)
-deleteItemsAtIndexPaths:
-layoutAttributesForElementsInRect:
-finalLayoutAttributes...: // Called for the item being deleted
-finalLayoutAttributes...: // \__ Called for each index path visible
-initialLayoutAttributes...: // / when deletion started
-applyLayoutAttributes: // Called for the item being deleted, to apply final layout attributes
// collection view begins scrolling up
-layoutSubviews: // Called multiple times as the
-layoutAttributesForElementsInRect: // collection view scrolls
// ... for any new set of
// ... attributes returned:
-collectionView:cellForItemAtIndexPath:
-applyLayoutAttributes: // Sets the standard attributes for the new cell
// collection view finishes scrolling
; , . , collectionView:cellForItemAtIndexPath: applyLayoutAttributes: , , ( hidden = NO).
, , , , , . UICollectionView, layoutSubviews, : _updateVisibleCellsNow:. , , , , , , .
, , , , , , /. , :
- (void)addCell
{
NSIndexPath *indexPathToInsert = [NSIndexPath indexPathForItem:self.numberOfItems
inSection:0];
self.numberOfItems++;
[self.collectionView insertItemsAtIndexPaths:@[indexPathToInsert]];
[self.collectionView scrollToItemAtIndexPath:indexPathToInsert
atScrollPosition:UICollectionViewScrollPositionCenteredVertically
animated:YES];
}
, , , , .
iOS 7 iOS 8 beta 5.