UICollectionView moveItemAtIndexPath:toIndexPath:不在屏幕上发出移动项目

时间:2012-12-04 07:49:36

标签: ios uicollectionview uicollectionviewcell

我正在尝试在iOS 6上的UICollectionView中重新排序项目。

我写了这段代码:

    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];

首先,我将项目的所有当前位置保存在字典中,然后我将项目分类到新位置,然后我将查看所有项目,并将它们从旧位置移动到新的。

当所有项目都显示在屏幕上时,此功能非常有效,但如果列表长度超过10则会使某些项目当前不可见(因为它们位于列表的可见部分的上方或下方),则会导致这些项目突然在可见索引中存在并动画到其他地方,当动画停止时它们被隐藏。 这看起来很奇怪,因为有些项目出现在其他人之上......

这是iOS 6 UICollectionView的问题,我在这里做错了吗?

1 个答案:

答案 0 :(得分:5)

看起来UICollectionView正在重复使用单元格,以使动画看起来很糟糕。屏幕外的所有单元都可以重复使用。

那为什么你的动画看起来很时髦?

单元格的开始和结束位置,如果它被隐藏或不被隐藏,当你移动单元格时,它们都会被自动处理。为了使这些动画看起来不错,您还需要更新数据源,因为代码使用它来确定单元格在动画期间应该在哪里开始和结束。

在调用索引更新块之前,请确保使用新索引位置更新数据源。通过这种方式,Apple的代码可以提供所需的信息,让您以更美观的方式移动您的单元格。

来自Apple documentation on UICollectionViews

  

要插入,删除或移动单个部分或项目,您必须执行以下步骤:

     
      
  1. 更新数据源对象中的数据。
  2.   
  3. 调用集合视图的相应方法以插入或删除节或项目。
  4.         

    在通知集合视图任何更改之前更新数据源至关重要。集合视图方法假定您的数据源包含当前正确的数据。如果没有,集合视图可能会从您的数据源收到错误的项目集,或者询问不存在的项目并使您的应用程序崩溃。