5

我无法为 a 中的部分之间的更改设置动画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:具有相同源和目标的那些,它不会改变任何东西。如果我不在批处理块中执行此操作,它显然会在第一个命令时崩溃。我忽略了什么吗?

4

2 回答 2

1

这篇关于 UICollectionView的非常有趣的文章的摘录:

在批量更新块中插入新部分时,不得将任何项目插入该部分 - 这将被隐式处理。事实上,在批量更新块中将项目插入新插入的部分会创建“幽灵”层,这些层会卡在集合视图层层次结构中。大概这只是 UICollectionView 的一个错误,因为没有记录此行为并且没有引发异常

知道了这一点,我发现删除部分并不奇怪,moveItemFromIndexPath:toIndexPath也不能很好地协同工作。我想这是“一种相同的错误”。

我使用的解决方案:

我在我应该删除的部分中放了一个假的隐形单元格。这使我可以保持与执行moveItemFromIndexPath:toIndexPath:. 当然,我相应地调整了我的数据源!

于 2014-02-03T16:03:45.670 回答
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];
于 2013-05-24T14:13:03.900 回答