- 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/
我在 Storyboard 中有一个 collectionView,如下所示: 注意约束:Collection View.top = Search Bar.bottom 我不想要该行上方的 Colle
我有一个包含两个部分的 Collection View ,每个部分都有一个项目。部分中的单元格包含 Collection View ,我需要使高度单元格适合内容 Collection View 。 我
我见过将 Collection View 嵌套在 TableView 中的解决方案,但对于我的应用程序,我需要有 2 个 Collection View ,因为这样可以更轻松地执行其他操作。 因此,让
感谢帮助。 如上所示,CollectionView ItemSize.height 比 CollectionView.height 大。我只是在 viewDidLayoutSubviews() 中设置
我有一个collectionview(A),它可以作为“卡片 View ”来滑动。在最后一个卡/单元格中,我有另一个 Collection View (B)来显示更多单元格。到目前为止,一切都很好!一
我正在寻找一种方法,当您滚动到 collectionView 中的另一个单元格时,可以更改 imageView 中的图像。 因此,当滚动单元格的 (1) 时,我想更改图像 (2)。 创建此内容的最佳方
我的 NSCollectionView 项目集成了另一个 NSCollectionView。一切都很好,但在第一个 View 中选择项目时就不行了。 当我设置collectionView1.isSel
我是一名 Android 开发者,正在尝试学习 iO 开发。 我正在尝试在水平分页滚动器内实现垂直滚动 UI(就像 ViewPager 内的 RecyclerView)。 我知道我应该使用嵌套的 UI
我在collectionView中有一个collectionView,我希望能够选择第二个collectionView中的一个单元格来执行到另一个ViewController的segue。 目前,当我
我有这两个代表: #pragma mark = UICollectionViewDataSource - (NSInteger)collectionView:(UICollectionView*)co
嘿,我正在尝试在我的动态 Collection View 单元格之后添加一个静态 Collection View 单元格。例如在我的屏幕截图中,在“Study Grind Edition” Colle
是否可以通过在 Collection View Cell .swift 文件中编写代码来阻止我的 Collection View 滚动。我希望能够在用户点击单元格中的按钮时停止滚动,然后在再次按下按钮
我有一个用例,我想要呈现一组collectionViews(或复合 View )。使用 marionette.js 执行此操作的最佳方法是什么? 我的模型结构如下- A | |-- Collectio
我有一个 View Controller ,其中有 tableView 和 Collection View 。我为 collectionView 和 tableView 设置了相同的高度。 前半部分是
在 Visual Studio 2017 中,尝试存档 Xamarin Android 项目时,成功构建后出现以下错误: 无法创建应用程序存档“MyArchive”。这种类型的 CollectionV
我对 Collection View 完全陌生,请帮助我在 Collection View 中垂直和水平滚动单元格: viewcontroller.h #import @interface View
我在一个表格 View 单元格中有两个不同的 collectionView。原因是因为我试图找到实现一个水平 collectionView 和一个显示不同数据的垂直 collecitonView 的最
我想在另一个 collectionview 标题中实现一个 Collection View 幻灯片,但是当我尝试连接 uicollectionview 的导出时,我收到一条错误消息,指出导出无法连接到
您好,我已经为这个问题苦苦挣扎了一段时间,一直想不出来。 我想做的是,在 collectionview 单元格内按下一个按钮,然后执行到下一个单元格的转换。 这是我想在 collectionview
在 collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayo
我是一名优秀的程序员,十分优秀!