gpt4 book ai didi

ios - CollectionView + UIKit Dynamics 在 performBatchUpdates 上崩溃 :

转载 作者:可可西里 更新时间:2023-11-01 03:26:14 24 4
gpt4 key购买 nike

我被一个奇怪的崩溃困住了,一整天都在尝试修复它。我有一个自定义的 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}'

我的模型得到了正确处理,我可以看到它从中移除了项目!

要删除的项目的索引路径在对象之间正确传递。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];
}

处理单元格属性的 CollectionView 委托(delegate)是下面的基本委托(delegate)。

- (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];
}

我已经尝试过但没有成功的事情:- 使布局无效- 重新加载数据- 从 UIDynamicAnimator 中删除行为并在更新后再次添加它们

有什么见解吗?

此存储库中提供了有问题的源代码。请检查一下。 Code Repository

最好的。乔治。

最佳答案

在与这个错误斗争了几周之后,我们的 friend @david-h 和@erwin 提供了一些有用的见解,以及来自 Apple 的 WWDR 的一些电话和电子邮件,我能够解决这个问题。只想与社区分享解决方案。

  1. 问题。 UIKit Dynamics 有一些辅助方法来处理 Collection View ,这些方法实际上并没有做一些我认为它应该自动做的内部事情,比如在使用 performBatchUpdates 的某些 Action 时自动更新动态动画单元格:被执行。因此,您必须根据 WWDR 手动执行此操作,因此我们迭代更新的 itens 更新它们的 NSIndexPaths,以便动态动画师可以为我们提供适当的单元格更新。

  2. 错误。即使在插入/删除单元格时执行此 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];
}
}

我打开了一个 Radar 来解释这个问题,希望 Apple 能够在未来的更新中解决这个问题。如果有人想复制它,可以在 OpenRadar 上找到它.

谢谢大家

关于ios - CollectionView + UIKit Dynamics 在 performBatchUpdates 上崩溃 :,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20567960/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com