9

我正在尝试在 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 的问题吗,我在这里做错了吗?

4

1 回答 1

5

看起来UICollectionView正在以使您的动画看起来很糟糕的方式重用单元格。任何离开屏幕的单元格都可以重复使用。

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

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

在调用索引更新块之前,请确保您的数据源已使用新的索引位置进行更新。这样一来,Apple 的代码就拥有了以更美观的方式移动您的细胞所需的信息。

来自关于 UICollectionViews 的 Apple 文档

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

  1. 更新数据源对象中的数据。
  2. 调用集合视图的适当方法来插入或删除部分或项目。

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

于 2012-12-09T21:06:37.403 回答