- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我被一个奇怪的崩溃困住了,一整天都在尝试修复它。我有一个自定义的 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 的一些电话和电子邮件,我能够解决这个问题。只想与社区分享解决方案。
问题。 UIKit Dynamics 有一些辅助方法来处理 Collection View ,这些方法实际上并没有做一些我认为它应该自动做的内部事情,比如在使用 performBatchUpdates 的某些 Action 时自动更新动态动画单元格:被执行。因此,您必须根据 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];
}
}
我打开了一个 Radar 来解释这个问题,希望 Apple 能够在未来的更新中解决这个问题。如果有人想复制它,可以在 OpenRadar 上找到它.
谢谢大家
关于ios - CollectionView + UIKit Dynamics 在 performBatchUpdates 上崩溃 :,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20567960/
我在 performBatchUpdates 期间面临崩溃的噩梦在 collection view 上. 问题基本上是这样的:我在服务器的目录中有很多图像。我想在 collection view 上显
我正在执行一些批量更新,不幸的是,当许多事件发生时,“插入”和“删除”项目的调用并不总是产生正确的结果。 因此,应用程序在 performBatchUpdates 中遇到异常。 因此,我尝试将 [co
我有一个 Collection View ,我修改它的项目大小,我通过调用它的 performBatchUpdates 方法来应用更改。 这会导致使用漂亮的动画进行更改,问题是,它还会禁用与我的 co
有一种方法可以自定义通过 performBatchUpdates 完成的动画计时吗? 我有这个代码 [self.stepCollectionView performBatchUpdates:^{
我在打电话 performBatchUpdates({ self.insertItemsAtIndexPaths(indexPathes) },
当我单独制作动画时,一切正常,但在 performBatchUpdates block 内部,更改是即时的,几乎就像我调用 reloadData() 一样。我是否正确使用它? 工作方式: NSAnim
我无法弄清楚这次崩溃的原因是什么? Incident Identifier: BF4459C1-B97D-448E-AAE0-4DA6A1E4731C CrashReporter Key: E72
我正在为我的 View Controller 使用快照测试。这是在测试中初始化 View Controller 的方式: window.addSubview(viewController.view)
我正在尝试使用 insertItemsAtIndexPaths 将新项目添加到我的 Collection View 中。我的应用程序在 performBatchupdate 时崩溃 - (void)
我有一个像这样更新的 UICollectionView: [self.collectionView performBatchUpdates:^{ [self.collectionView de
我们正在尝试设置具有自定义布局的 UICollectionView。每个 CollectionViewCell 的内容都是一张图片。总的来说,将有几千张图像,并且在某个特定时间大约有 140-150
我有一个 UITableView,它显示来自多个 RSS 提要的帖子的聚合提要。每当我的应用程序从提要中提取新帖子时,我都会创建一个对象来表示更新 UITableView 当前行所需的所有插入和删除操
我注意到 performBatchUpdates:completion: 的方式有一个奇怪的不同。 UICollectionView的方法适用于 iOS7(坏 - 崩溃)和 iOS8(好)。这是我使用
我目前遇到的有趣问题。在 UICollectionView 实例上调用 PerformBatchUpdates 方法时,某些情况会导致完成处理程序无法执行。 collectionView.perfor
我正在使用这个 gist用于 FRC 和 UICollectionView。这在 iOS 9 之前一直运行良好。 现在,在 iOS 10 中,有时我的应用程序会在 collectionview 的 p
如果我旋转设备而 collectionview performBatchUpdate 和 reloadItemsAtIndexPaths , Collection View 将错位。但 View 仍将
我从分成页面的 API 获取数据,我用户 var hasMoreUsers: Bool显示/隐藏页脚单元格 func collectionView(collectionView: UICollecti
我正在编写自定义 UICollectionViewFlowLayout 并且我注意到 initialLayoutAttributesForAppearingItemAtIndexPath: 和 ini
我刚刚调试完一个非常讨厌的 UIViewController 漏洞,这样即使在调用 dismissViewControllerAnimated 之后 UIViewController 也没有被释放。
好的,基本概述。我有一个 UICollectionView,我需要它支持通过 performBatchUpdates: 方法添加和删除项目。如果我使用标准的 UICollectionViewFlowL
我是一名优秀的程序员,十分优秀!