~ read.

Some problems with refresh UICollectionView

May flash on the screen

  • Sometiems you may find your collectionView has a phenomenon of flash when you call reloadData which is because adding cells is in layoutSubviews method, as layoutSubViews will be called in the next runloop after call reloadData, in this case the visibleCells method may return nil, so the flash occur.
    • How to fix it ? You may call layoutSubViews manually as followed:
//BUG:
    [self.collectionView reloadData];
//Solution:
    [self.collectionView reloadData];
    [self.collectionView setNeedsLayout];
    [self.collectionView layoutIfNeeded];

How to refresh without Animation

  • If you partial refresh with UICollectionView like insert, reload, delete, these methods may have a default animation, here are some ways to remove it:
//One way:
[UIView setAnimationsEnabled:NO];
[collectionView performBatchUpdates:^{
    [collectionView reloadItemsAtIndexPaths:indexPaths];
} completion:^(BOOL finished) {
    [UIView setAnimationsEnabled:YES];
}];
//Besides:
[UIView animateWithDuration:0 animations:^{
    [collectionView performBatchUpdates:^{
        [collectionView reloadItemsAtIndexPaths:indexPaths];
    } completion:nil];
}];
//In addition:
[UIView performWithoutAnimation:^{
    [self.collectionView reloadItemsAtIndexPaths:indexPaths];
}];

How to refresh without Animation reference


Asynchronous refresh problem

  • If your App contain high-performance rendering requirements with attributes like Weibo or Wechat's message list you may use asynchronous text fresh framework like YYText. You may have the problem with text flash when you call collectionView's reloadData method github link
  • Solution: you may replace reload all data method with reload partial data method as followed:
//insert data:
@try{
     [self.collectionView performBatchUpdates:^{
            [self.datas insertObjects:items];
            [collectionView insertItemsAtIndexPaths:indexPaths];
     } completion:^(BOOL finished) {
     }];
}
@catch ( NSException * e ) {
     [self reloadCollectionView];
}
//reload data:
@try{
     [self.collectionView performBatchUpdates:^{
            [self.datas replaceItems:items];
            [collectionView reloadItemsAtIndexPaths:indexPaths];
     } completion:^(BOOL finished) {
     }];
}
@catch ( NSException * e ) {
     [self reloadCollectionView];
}
//remove data:
@try{
     [self.collectionView performBatchUpdates:^{
            [self.datas deleteItems:items];
            [collectionView deleteItemsAtIndexPaths:indexPaths];
     } completion:^(BOOL finished) {
     }];
}
@catch ( NSException * e ) {
     [self reloadCollectionView];
}
  • As you can see, using @try-catch syntactic can avoid crashing after refresh failed, once you failed you can call collectionView realoadData to refresh all the UICollectionView instead.
comments powered by Disqus