我遇到了一些麻烦,我想知道是否有人可以提供一些指导。

我正在尝试按以下顺序创建节标题:[“Push”,“Busy”,“Finished”,“Canceled”]。

不幸的是,这个顺序不能通过简单的“升序是/否”来实现...我必须添加一个自定义的比较选择器...这样的东西..:

**“状态”映射到[“推送”,“繁忙”,“完成”,“取消”]的位置

NSSortDescriptor *sortStates = [NSSortDescriptor sortDescriptorWithKey:@"states"
                                                           ascending:NO
                                                            selector:@selector(compareCustom:)];

因此,我实现了一个“compareCustom” ...但是,事实证明,由于以下异常结果,我无法实现自定义排序器:

***由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“不支持的NSSortDescriptor选择器:compareCustom:”

供参考,sortDate由以下方式实现:
request.sortDescriptors = @[sortStates]
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                    managedObjectContext:context
                                                                    sectionNameKeyPath:@"states"
                                                                               cacheName:nil];

看来我无法实现一个返回NSComparisonResult的compareCustom吗?我觉得应该有可能。但是我不知道怎么做。如果有人可以提供一些建议,我将不胜感激!

还供参考,这是我的“compareCustom”方法
-(NSComparisonResult)compareCustom:(NSString *)anotherState {
if ([(NSString *)self isEqualToString:@"Push"] && [anotherState isEqualToString:@"Canceled"]) {
    return NSOrderedDescending;
}

else if ([(NSString *)self isEqualToString:@"Push"] && [anotherState isEqualToString:@"Busy"]) {
    return NSOrderedDescending;
}

else if ([(NSString *)self isEqualToString:@"Push"] && [anotherState isEqualToString:@"Finished"]) {
    return NSOrderedDescending;
}

else if ([(NSString *)self isEqualToString:@"Push"] && [anotherState isEqualToString:@"Push"]) {
    return NSOrderedSame;
}

else if ([(NSString *)self isEqualToString:@"Finished"] && [anotherState isEqualToString:@"Canceled"]) {
    return NSOrderedDescending;
}

else if ([(NSString *)self isEqualToString:@"Finished"] && [anotherState isEqualToString:@"Busy"]) {
    return NSOrderedAscending;
}
else if ([(NSString *)self isEqualToString:@"Finished"] && [anotherState isEqualToString:@"Finished"]) {
    return NSOrderedSame;
}
else if ([(NSString *)self isEqualToString:@"Finished"] && [anotherState isEqualToString:@"Push"]) {
    return NSOrderedAscending;
}

else if ([(NSString *)self isEqualToString:@"Busy"] && [anotherState isEqualToString:@"Finished"]) {
    return NSOrderedDescending;
}
else if ([(NSString *)self isEqualToString:@"Busy"] && [anotherState isEqualToString:@"Canceled"]) {
    return NSOrderedDescending;
}

else if ([(NSString *)self isEqualToString:@"Busy"] && [anotherState isEqualToString:@"Busy"]) {
    return NSOrderedSame;
}

else if ([(NSString *)self isEqualToString:@"Busy"] && [anotherState isEqualToString:@"Push"]) {
    return NSOrderedAscending;
}

else {
    return NSOrderedSame;
}
}

最佳答案

根据documentation的自定义排序不适用于SQLite持久存储:

另一方面,SQL存储会编译谓词和排序
SQL的描述符,并在数据库本身中评估结果。
这样做主要是为了提高性能,但这意味着评估
发生在非可可环境中,因此对描述符进行排序(或
谓词)依靠可可就行不通。支持的排序
选择器是compare:和caseInsensitiveCompare :、 localizedCompare :、
localizedCaseInsensitiveCompare:和localizedStandardCompare:(
后者是类似Finder的排序方式,大多数人应该使用
时间)。另外,您不能使用
SQLite存储。

因此,看来您不能简单地强制NSFetchedResultsController以字母顺序以外的方式显示节。

但是您可以使用解决方法。向您的实体添加其他整数类型的持久属性(我们将其称为sectionOrder)。根据states属性设置其值(因此"Push"的值为0,"Busy"的值为1。)例如,您可以在awakeFromInsert方法中进行设置。

然后在排序描述符中将@"sectionOrder"用作sectionNameKeyPath和键路径。您可以使用此UITableViewDataSource方法将板块标题设置为“推”,“忙”等:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.controller sections] objectAtIndex:section];
    return [sectionInfo.objects.firstObject name];
}

归功于excellent answer

07-25 21:49