在部分之间重新排列项目时,UICollectionView会崩溃

时间:2013-05-24 13:57:52

标签: ios crash uicollectionview

我无法设置UICollectionView中各个部分之间的更改动画,我的程序一直在崩溃,它有什么问题?

我有一个集合视图,它有四个部分:

  

0:A
  1:B
  2:C
  3:D

我想将其转换为只有三个具有相同项目的部分:

  

0:A
  1:B,C
  2:D

我想为这种转变制作动画:

// Initial state

NSArray *source = @[ @[@"A"], @[@"B"], @[@"C"], @[@"D"] ];


// Some data source methods

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return [source[section] count];
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return [source count];
}


// Transformation: that works but I have to keep an empty section

source = @[ @[@"A"], @[@"B", @"C"], @[@"D"], @[] ];

[collection performBatchUpdates:^{
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]
                        toIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]
                        toIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]];
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:2]
                        toIndexPath:[NSIndexPath indexPathForItem:1 inSection:1]];
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:3]
                        toIndexPath:[NSIndexPath indexPathForItem:0 inSection:2]];
} completion:nil];


// Transformation: that crashes!

source = @[ @[@"A"], @[@"B", @"C"], @[@"D"] ];

[collection performBatchUpdates:^{
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]
                        toIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]
                        toIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]];
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:2]
                        toIndexPath:[NSIndexPath indexPathForItem:1 inSection:1]];
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:3]
                        toIndexPath:[NSIndexPath indexPathForItem:0 inSection:2]];
    [collection deleteSections:[NSIndexSet indexSetWithIndex:3]];
} completion:nil];

我一直在崩溃,内部断言失败:Assertion failure in -[UICollectionView _endItemAnimations]...,有时甚至更奇怪,一个malloc错误:incorrect checksum for freed object...

如果我不打电话deleteSections:它也不起作用。如果我先放,它不会改变任何东西。如果我删除具有相同源和目标的moveItemAtIndexPath:toIndexPath:,则不会更改任何内容。如果我不在批处理块中执行它,它显然会在第一个命令崩溃。 我忽视了什么吗?

2 个答案:

答案 0 :(得分:1)

这个非常有趣的article关于UICollectionView的摘录:

  

在批量更新块中插入新部分时,必须使用   不要将任何项目插入该部分 - 这将被处理   含蓄。实际上,将项目插入到新插入的部分中   批量更新块会创建“鬼”层,这些层会卡在   集合视图层层次结构。据推测,这只是一个错误   UICollectionView,因为此行为未记录且无异常   扔了

知道了这一点,我发现删除部分并且moveItemFromIndexPath:toIndexPath也不能很好地结合在一起并不奇怪。我想这是“有点同样的错误”。

我使用的解决方案:

我在我应该删除的部分放了一个假的隐形单元格。这让我保持了同样的行为,就像我做了moveItemFromIndexPath:toIndexPath:一样。当然,我相应调整了我的数据源!

答案 1 :(得分:0)

你有没有试过像:

source = @[ @[@"A"], @[@"B", @"C"], @[@"D"] ];

[collection performBatchUpdates:^{
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:2]
                        toIndexPath:[NSIndexPath indexPathForItem:1 inSection:1]];
    [collection deleteSections:[NSIndexSet indexSetWithIndex:2]];
} completion:nil];