【问题标题】:Sorting NSArray of NSDictionary...not completely working对 NSDictionary 的 NSArray 进行排序...不完全工作
【发布时间】:2015-07-04 10:05:56
【问题描述】:

所以我有 NSDictionary 项的 NSMutableArray。每个 NSDictionary 项都有一个键“名称”,应该用于按字母顺序对数组进行排序。除了它的“排序”部分有效。它没有按确切的字母顺序排序。它按顺序移动了一些字典,但留下了一些乱序。

NSMutableArray *section1 = [champs lastObject];
NSArray *oldSection1 = [NSArray arrayWithArray:section1];
[section1 sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    NSDictionary *dictA = (NSDictionary *)obj1;
    NSDictionary *dictB = (NSDictionary *)obj2;

    NSString *champName1 = dictA[@"name"];
    NSString *champName2 = dictB[@"name"];
    return [champName1 compare:champName2];
}];
// Animation
for (NSDictionary *champInfo2 in section1) {
    if ([oldSection1 indexOfObject:champInfo2] != [section1 indexOfObject:champInfo2]) {
        [self.collectionView moveItemAtIndexPath:[NSIndexPath indexPathForItem:[oldSection1 indexOfObject:champInfo2] inSection:1] toIndexPath:[NSIndexPath indexPathForItem:[section1 indexOfObject:champInfo2] inSection:1]];
    }
}

我什至试过这段代码

NSMutableArray *section1 = [champs lastObject];
NSArray *oldSection1 = [NSArray arrayWithArray:section1];
/*[section1 sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    NSDictionary *dictA = (NSDictionary *)obj1;
    NSDictionary *dictB = (NSDictionary *)obj2;

    NSString *champName1 = dictA[@"name"];
    NSString *champName2 = dictB[@"name"];
    return [champName1 compare:champName2];
}];*/
section1 = [[NSArray arrayWithArray:section1] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]].mutableCopy;
// Animation
for (NSDictionary *champInfo2 in section1) {
    if ([oldSection1 indexOfObject:champInfo2] != [section1 indexOfObject:champInfo2]) {
        [self.collectionView moveItemAtIndexPath:[NSIndexPath indexPathForItem:[oldSection1 indexOfObject:champInfo2] inSection:1] toIndexPath:[NSIndexPath indexPathForItem:[section1 indexOfObject:champInfo2] inSection:1]];
    }
}

好的,问题是我没有在重组之前更新我的内容快照,因为我在视觉上更新了它。更新代码:

// Animation
                for (NSDictionary *champInfo2 in section) {
                    if ([oldSection indexOfObject:champInfo2] != [section indexOfObject:champInfo2]) {
                        [self.collectionView moveItemAtIndexPath:[NSIndexPath indexPathForItem:[oldSection indexOfObject:champInfo2] inSection:[champs indexOfObject:section]] toIndexPath:[NSIndexPath indexPathForItem:[section indexOfObject:champInfo2] inSection:[champs indexOfObject:section]]];
                        [oldSection removeObject:champInfo2];
                        [oldSection insertObject:champInfo2 atIndex:[section indexOfObject:champInfo2]];
                    }
                }

【问题讨论】:

    标签: ios objective-c sorting


    【解决方案1】:

    要执行多个 UICollectionView 项更新(插入/删除/移动),建议使用performBatchUpdates:completion:。否则你可能会遇到无效的索引。

    Link to official Apple's documentation

    【讨论】:

      【解决方案2】:

      代码的上半部分(即排序)工作正常。如果你使用排序描述符,它可以被简化,但这绝对不是问题。

      真正的问题在于移动事物的代码。

      在第一次移动之前,oldSection1self.collectionView 的索引是同步的,即如果一个项目XYZoldSection1 的索引i 处,那么它也在i 的索引处self.collectionView.

      然而,在第一次移动之后,索引会不同步,因为移动只在self.collectionView 中执行,而不是在oldSection1 中执行。例如,如果您以

      oldSection1    = C D A B
      collectionView = C D A B
      

      你希望它成为

      sorted =         A B C D
      

      C 的第一步之后,数据将看起来像

      oldSection1    = C D A B
      collectionView = A C D B
      

      当需要将 D 移动到新位置时,C 会被移动。

      要解决此问题,请将oldSection1 设置为可变,并在self.collectionView 中移动时执行“平行”移动。

      【讨论】:

      • 明白。所以现在我在集合视图中移动该项目,然后在移动下一个项目之前将其移动到内容的旧快照中。
      • 如果您的数组很大(比视图大得多),您可以计算显示的项目范围,并检查排序后仍会显示多少项目。如果大部分或许多不可见,例如因为您更改了排序顺序(比如人们按生日而不是姓氏排序),您可能只是重新加载整个数组。
      【解决方案3】:

      看起来您的实际 数据 是正确的,但您的 collection view 显示不正确,因为您正在迭代数据,一次移动一排。这很可能会导致对已经重新排序的行重新排序。

      调用 [self.collectionView reloadData] 而不是手动移动行应该可以解决此问题。

      【讨论】:

      • 我正在尝试使用 moveItemAtIndexPath: 来提供一个漂亮的动画而不是它出现的“噗”声。
      • @TechGenius 好的。不过,这是否至少显示了正确的数据?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多