I have trouble animating changes between sections in a UICollectionView
, my program keeps crashing, what is wrong with it?
I have a collection view which has four sections:
0: A
1: B
2: C
3: D
I want to transform it to have only three sections with the same items:
0: A
1: B, C
2: D
And I want to animate this transformation:
// 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];
I keep getting crashes, either an internal assertion failure: Assertion failure in -[UICollectionView _endItemAnimations]...
, or sometimes, even more weird, a malloc error: incorrect checksum for freed object...
.
If I don't call deleteSections:
it doesn't work either. If I put first, it doesn't change anything. If I remove the moveItemAtIndexPath:toIndexPath:
which have the same source and destination, it doesn't change anything. If I don't do it in a batch block, it obviously crashes at the first command.
Did I overlook something?
An extract from this very interesting article about UICollectionView:
When inserting a new section within the batch update block, one must not insert any items into that section – that will be handled implicitly. In fact, inserting items into a newly-inserted section in a batch update block creates “ghost” layers which get stuck in the collection view layer hierarchy. Presumably this is a just bug with UICollectionView, as this behavior is not documented and no exception is thrown
Knowing this, I find it not surprising at all that deleting of section and moveItemFromIndexPath:toIndexPath
do not work well together either. I guess it's "kind of the same bug".
The solution I used:
I put a fake invisible cell in the section I should have deleted. That permitted me to keep the same behavior as if I had done a moveItemFromIndexPath:toIndexPath:
. Of course, I adapted my datasource accordingly!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With