Repeated UICollectionView Animation

I create a collection view with all the basic materials, for example, by default FlowLayout, a unique section.
I assume that I am using collectionView:CellForItemAtIndexPath: correctly collectionView:CellForItemAtIndexPath: and all other dataSource protocols

I have mainData , which is an array of dictionaries (source data), mainDataReferenceOrdered , mainDataNameOrdered and mainDataQuantiteOrdered are other arrays containing the same data as mainData (the same elements are specified). <t> dataToDisplay - current controller array pointer for ordered data.

When reordering, I just modify the data in the batch collection, for example:

 [itemCollectionControl.collectionView performBatchUpdates:^{ dataToDisplay = mainDataReferenceOrdered; //or any other ordered array [itemCollectionControl.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, itemCollectionControl.collectionView.numberOfSections)]]; } completion:^(BOOL finished) {}]; 

But the collection disappears in all cells, even if they are already visible or in the right place.

I read Apple 's documentation on UICollectionView , but I don't know what I missed. I also read other topics about this, but still looking for how I should do it.

What does the package expect to find out which animation will apply to the cells?


My decision

This is the last code that I use, by far the closest to iOS programming that I assume.

 [itemCollectionControl.collectionView performBatchUpdates:^{ NSArray *oldOrder = dataToDisplay; dataToDisplay = mainDataNBContainersOrdered; for (NSInteger i = 0; i < oldOrder.count; i++) { NSIndexPath *fromIndexPath = [NSIndexPath indexPathForRow:i inSection:0]; NSInteger j = [dataToDisplay indexOfObject:oldOrder[i]]; NSIndexPath *toIndexPath = [NSIndexPath indexPathForRow:j inSection:0]; [itemCollectionControl.collectionView moveItemAtIndexPath:fromIndexPath toIndexPath:toIndexPath]; } } completion:^(BOOL finished) { if (finished) { [itemCollectionControl.collectionView reloadData]; } }]; 

I just go through all the old ordered elements, check their new position and apply it with -[UICollectionView moveItemAtIndexPath:toIndexPath:]
There are still some duplicated cell glitches, but it looks great on iOS7 (not iOS6). Termination may be useless on iOS7, I forcibly returned the order at the end when shuffling iOS6.

Edit

I think I found a solution, but I can no longer test this project. Perhaps adding only two lines of code should fix this terrible glitch.

before any call -[UICollectionView moveItemAtIndexPath:toIndexPath:] , call -[UICollectionView beginUpdates] and, finally, after all the moves -[UICollectionView endUpdates] .

If anyone can verify that it works, tell me.

+6
source share
1 answer

In the collection view, the identity of the elements in your data model is not known, so it does not know that they have moved. Therefore, you need to explicitly specify the collection view in which each cell moves inside the batch update using moveItemAtIndexPath:toIndexPath: You can calculate this yourself by looping through the elements in the from array and looking at their positions in the array. Something like this (printed from memory, so sorry for any typos):

 [itemCollectionControl.collectionView performBatchUpdates:^{ for (NSInteger i = 0; i < mainDataReferenceOrdered.count; i++) { NSIndexPath *fromIndexPath = [NSIndexPath indexPathForRow:i inSection:0]; NSInteger j = [mainDataNameOrdered indexOfObject:mainDataReferenceOrdered[i]]; NSIndexPath *toIndexPath = [NSIndexPath indexPathForRow:j inSection:0]; [itemCollectionControl.collectionView moveItemAtIndexPath:fromIndexPath toIndexPath:toIndexPath]; } } completion:^(BOOL finished) {}]; 

If you have many (several thousand) items, you may want to use sets for faster searches.

A more common approach is to use something like TLIndexPathTools , which can calculate batch updates for you. Take a look at the Shuffle sample project.

+5
source

Source: https://habr.com/ru/post/956498/


All Articles