在将项目添加到项目后,我刚刚遇到了类似/相同的问题UICollectionView
.
发生了什么
问题似乎是紧随其后[collectionView reloadData]
or [collectionView insertItemsAtIndexPaths: @[newItemIndexPath]]
, 集合视图的内容大小尚未更新.
如果你随后尝试滚动添加的项目可见,它会失败,因为内容矩形尚不包含新项目的空间.
A fix
有一个简单且相当可靠的解决方法,即将滚动事件发布到运行循环的下一次迭代,如下所示:
const NSUInteger newIndex =
[self collectionView: self.collectionView numberOfItemsInSection: 0] - 1;
NSIndexPath *const newPath =
[NSIndexPath indexPathForItem: newIndex
inSection: 0];
[self.collectionView insertItemsAtIndexPaths: @[newPath]];
UICollectionViewLayoutAttributes *const layoutAttributes =
[self.collectionView layoutAttributesForItemAtIndexPath: newPath];
dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView scrollRectToVisible: layoutAttributes.frame
animated: YES];
});
难道就没有更好的修复方法吗?
虽然它有效,但这种“在下一个运行循环标记上发布滚动调用”的恶作剧感觉很黑客。
如果UICollectionView
当它完成更新内容矩形时可以调用回调。 UIKit 对于对其模型执行异步更新的其他方法具有这种风格的回调。例如,一个完成块UIViewController
过渡和UIView
动画。
UICollectionView
不提供此回调。据我所知,没有其他简单干净的方法来查找它何时完成更新。如果没有这个,下一个运行循环蜱是我们更愿意使用的回调独角兽的可行马代理。
还有什么要知道的吗?
知道这一点可能很有用UITableView
也有这个问题。类似的解决方法也应该在那里起作用。