我有一个像这样更新的UICollectionView:
[self.collectionView performBatchUpdates:^{
[self.collectionView deleteItemsAtIndexPaths:pathsRemoved];
[self.collectionView insertItemsAtIndexPaths:pathsAdded];
}
通常情况下,这很好用,但在某些情况下,数据源计数与原始项目数不匹配 - 路径数量已删除+已添加路径数量。
因此,我将此代码包装在@ try / @ catch块中,然后调用[self.collectionView reloadData]。
然而,最终发生的事情是,重新加载数据后,布局变得混乱;之前存在的细胞(在屏幕上方的细胞上,但在屏幕外)不再显示。集合视图的内容大小是正确的,我可以向上向上滚动,但只能看到重新加载时屏幕上的单元格。
有趣的是,Reveal.app显示其他细胞确实存在,但是隐藏了;我有一种预感,这是一个红色的鲱鱼,并且这里有一些视图缓存,但是细胞仍然列在Reveal中。
我已经尝试使布局无效,调用layoutIfNeeded,以及我找到的各种子流的布局技巧,并没有修复它。
我通过做自己的良性断言来解决问题,并进行检查以确保计数加起来。如果他们这样做,执行BundUpdates。否则,不要打扰,只是重新加载。这是有效的,因为我们完全绕过了performBatchUpdates:但我不得不问:
是否有更好的方法可以从performBatchUpdates中抛出的断言异常中优雅地恢复:?或者是UICollectionViews只是错误(仍然在iOS 7上)。
答案 0 :(得分:2)
我只是想办法解决这个问题!
我试着把performBatchUpdates:代码包装在调用[collectionView reloadData]的@ try / @ catch块中。
然后我意识到当我的ViewController被取消分配时,问题也消失了,而collectionView也是。
所以我找到了丑陋的解决方案(但正在工作):杀死旧的collectionView并在catch块中创建一个新的。
@try {
[collectionView performBatchUpdates:^ {
// Do your stuff
}];
}
@catch (NSException *exception) {
UIView *oldSuperview = self.collectionView.superview;
[self.collectionView removeFromSuperview];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.collectionView.frame collectionViewLayout:self.collectionView.collectionViewLayout];
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
// set other collectionView's properties here
[oldSuperview addSubview:self.collectionView];
}
我知道这很糟糕,但它救了我!