Geo*_*oas 7 objective-c ios uicollectionview uicollectionviewlayout uikit-dynamics
我遇到了一个奇怪的崩溃并试图整天修复它.我有一个自定义UICollectionViewLayout,它基本上增加了细胞的重力和碰撞.
实施效果很好!当我尝试使用以下命令删除一个单元格时会出现问题:[self.collectionView performBatchUpdates:].
它给了我以下错误:
2013-12-12 21:15:35.269 APPNAME[97890:70b] *** Assertion failure in -[UICollectionViewData validateLayoutInRect:], /SourceCache/UIKit_Sim/UIKit-2935.58/UICollectionViewData.m:357
2013-12-12 20:55:49.739 APPNAME[97438:70b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView recieved layout attributes for a cell with an index path that does not exist: <NSIndexPath: 0x975d290> {length = 2, path = 0 - 4}'
Run Code Online (Sandbox Code Playgroud)
我的模型处理正确,我可以看到它从中删除项目!
要删除的项的indexPaths正在对象之间正确传递.collectionView更新没有崩溃的唯一时间是我删除它上面的最后一个单元格,否则,崩溃就会发生.
这是我用来删除单元格的代码.
- (void)removeItemAtIndexPath:(NSIndexPath *)itemToRemove completion:(void (^)(void))completion
{
UICollectionViewLayoutAttributes *attributes = [self.dynamicAnimator layoutAttributesForCellAtIndexPath:itemToRemove];
[self.gravityBehaviour removeItem:attributes];
[self.itemBehaviour removeItem:attributes];
[self.collisionBehaviour removeItem:attributes];
[self.collectionView performBatchUpdates:^{
[self.fetchedBeacons removeObjectAtIndex:itemToRemove.row];
[self.collectionView deleteItemsAtIndexPaths:@[itemToRemove]];
} completion:nil];
}
Run Code Online (Sandbox Code Playgroud)
处理单元属性的CollectionView委托是下面的基本委托.
- (CGSize)collectionViewContentSize
{
return self.collectionView.bounds.size;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
return [self.dynamicAnimator itemsInRect:rect];
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
return [self.dynamicAnimator layoutAttributesForCellAtIndexPath:indexPath];
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试过的事情没有成功: - 使布局无效 - 重新加载数据 - 从UIDynamicAnimator中删除行为并在更新后再次添加它们
任何见解?
此存储库中提供了有问题的源代码.请检查一下.代码库
最好.乔治.
Geo*_*oas 12
经过几周的努力,这个bug,我们的朋友@ david-h和@erwin的一些有用的见解以及来自Apple的WWDR的一些电话和电子邮件,我能够解决这个问题.只想与社区分享解决方案.
问题.UIKit Dynamics有一些帮助方法来处理集合视图,这些方法实际上并没有做我认为应该自动执行的内部工作,比如在执行某些使用performBatchUpdates:的操作时自动更新动态动画单元格.所以你必须根据WWDR手动完成,所以我们迭代更新的itens更新他们的NSIndexPaths,这样动态动画师可以给我们正确的单元更新.
错误.即使对单元格插入/删除执行此indexPath更新,我也会在动画中出现大量随机崩溃和奇怪的行为.所以,我按照@erwin给出的一个提示,包括在performBatchUpdates之后重新实例化UIDynamicAnimator,并解决了这种情况下的所有问题.
所以代码.
- (void)removeItemAtIndexPath:(NSIndexPath *)itemToRemove completion:(void (^)(void))completion
{
UICollectionViewLayoutAttributes *attributes = [self.dynamicAnimator layoutAttributesForCellAtIndexPath:itemToRemove];
if (attributes) {
[self.collisionBehaviour removeItem:attributes];
[self.gravityBehaviour removeItem:attributes];
[self.itemBehaviour removeItem:attributes];
// Fix the problem explained on 1.
// Update all the indexPaths of the remaining cells
NSArray *remainingAttributes = self.collisionBehaviour.items;
for (UICollectionViewLayoutAttributes *attributes in remainingAttributes) {
if (attributes.indexPath.row > itemToRemove.row)
attributes.indexPath = [NSIndexPath indexPathForRow:(attributes.indexPath.row - 1) inSection:attributes.indexPath.section];
}
[self.collectionView performBatchUpdates:^{
completion();
[self.collectionView deleteItemsAtIndexPaths:@[itemToRemove]];
} completion:nil];
// Fix the bug explained on 2.
// Re-instantiate the Dynamic Animator
self.dynamicAnimator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self];
[self.dynamicAnimator addBehavior:self.collisionBehaviour];
[self.dynamicAnimator addBehavior:self.gravityBehaviour];
[self.dynamicAnimator addBehavior:self.itemBehaviour];
}
}
Run Code Online (Sandbox Code Playgroud)
我开了一个雷达解释了这个问题,希望Apple能够在未来的更新中解决这个问题.如果有人复制它,它可以在OpenRadar上使用.
谢谢大家.
| 归档时间: |
|
| 查看次数: |
4984 次 |
| 最近记录: |