Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UICollectionView moveItemAtIndexPath:toIndexPath: issues moving items not on screen

I'm trying to animate a re-sort of items in UICollectionView on iOS 6.

I wrote this code:

    NSMutableDictionary *from = [NSMutableDictionary dictionaryWithCapacity:self.count];
    for (int ii = 0; ii < self.count; ii++) {
        MyItem item = [self getItemAtIndex:(NSInteger)ii];
        [from setObject:[NSNumber numberWithInt:ii] forKey:[NSNumber numberWithInt:item.id]];
    }

    [self sort];

    [self.collectionView performBatchUpdates:^{
        for (int ii = 0; ii < self.count; ii++) {
            MyItem item = [self getItemAtIndex:(NSInteger)ii];
            NSNumber *prevPos = (NSNumber *)[from objectForKey:[NSNumber numberWithInt:item.id]];
            if ([prevPos intValue] != ii) {
                NSIndexPath *from = [NSIndexPath indexPathForItem:prevPos.intValue inSection:0];
                NSIndexPath *to = [NSIndexPath indexPathForItem:ii inSection:0];
                [self.collectionView moveItemAtIndexPath:from toIndexPath:to];
            }
        }
    } completion:nil];

So first, I'm saving all the current locations of the items in a dictionary, then I'm sorting the items into new positions, then I'm going over all items, and moving them from the old position to the new one.

This works great when all items are displayed on the screen, but if the the list if longer then 10 which makes some items not currently visible (since they are above or below the visible section of the list), it causes these items to suddenly pop into existence in visible indexes and get animated into other places, and when the animation stops they are hidden. This looks really bizarre as there are items that appear on top of others...

Is this an issue with iOS 6 UICollectionView, and am I doing something wrong here?

like image 692
marmor Avatar asked Dec 04 '12 07:12

marmor


1 Answers

It looks like UICollectionView is reusing cells in such a way as to make your animation look bad. Any cells that go offscreen become available for reuse.

So why is your animation looking funky?

The starting and ending location of a cell, and if it gets hidden or not, is all taken care of automatically when you move cells around. For those animations to look good, you need to also update your data source, as it appears the code uses that to determine where cells should start and end during the animation.

Before you call your index update block, make sure your data source is updated with the new index locations. That way Apple's code has the information it needs to move your cells around in a more, lets say, aesthetically pleasing manner.

From the Apple documentation on UICollectionViews:

To insert, delete, or move a single section or item, you must follow these steps:

  1. Update the data in your data source object.
  2. Call the appropriate method of the collection view to insert or delete the section or item.

It is critical that you update your data source before notifying the collection view of any changes. The collection view methods assume that your data source contains the currently correct data. If it does not, the collection view might receive the wrong set of items from your data source or ask for items that are not there and crash your app.

like image 181
redlightbulb Avatar answered Sep 22 '22 18:09

redlightbulb