带有NSFetchedResultsController的UITableView:对每个部分彼此独立地排序

时间:2013-10-30 23:42:58

标签: ios objective-c uitableview core-data nsfetchedresultscontroller

我正在开发核心数据应用程序。我有一个主表,显示具有不同状态的订单:新建,已接受,已交付等。

我遇到的问题是我需要按照不同的标准订购每个部分。例如:

  • 新订单需要按最旧的订单排序。
  • 接受的订单需要按照最快的顺序进行排序。
  • 交付的订单需要按最新排序。

所以这是我在获取结果时的代码:

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"CDOrder"];
request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"orderPosition" ascending:YES],[NSSortDescriptor sortDescriptorWithKey:@"createdDate" ascending:NO]];  

User* user = [User getInstance];
NSDate *TwelveHoursAgo = [NSDate dateWithTimeIntervalSinceNow:-3600 * 12];

request.predicate = [NSPredicate predicateWithFormat:@"(servicePersonId == %@) AND (createdDate >= %@)", [NSNumber numberWithLong:user.userId], TwelveHoursAgo];
ordersTableViewController.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:super.managedObjectContext sectionNameKeyPath:@"orderPosition" cacheName:nil];

正如您所看到的,这是基于"orderPosition"创建部分并按"createdDate"排序所有订单。但我需要按"deliverDate"

订购某些订单

由于

1 个答案:

答案 0 :(得分:3)

我可以想办法解决这个问题。

方法一:为每个部分使用单独的NSFetchedResultsController。这样,您可以为每个部分使用不同的搜索描述符。这将一些模型细节与您的控制器联系起来,这意味着如果您计划创建新的状态类型,则需要修改控制器和模型。

实现此目的的最简单方法是创建不同NSFetchedResultsControllers的数组。数组中的项目数是节数。但请注意,这样做可能会导致表视图中出现空白部分。例如,如果没有任何接受的订单,您可能仍会在UITableView中找到“接受的订单”部分。

在某一点上,这可能变得足够复杂以保证将此代码放入其自己的自定义结果控制器中,该控制器在内部管理NSFetchedResultsControllers列表并公开与NSFetchedResultsController类似或相同的外部接口。

方法二:在模型中添加一个特殊字段作为排序字段,然后自动更新该字段以按照您喜欢的方式保持排序顺序。例如,对于状态为“的订单”新“您只需将订单日期存储在此字段中。对于具有“已接受”状态的订单,您可以存储交货日期。对于具有“已交付”状态的订单,您希望存储订单日期,但您希望它处于反方向。按顺序实现此逆转的最简单方法是存储订单日期乘以-1。

NSDate只是一个简单原语的包装器,它存储了所表示日期和2001年1月1日之间的时间间隔。您可以使用以下代码轻松地将该数字乘以-1:

float interval = [orderDate timeIntervalSinceReferenceDate];
NSDate *reversedDate = [NSDate dateWithTimeIntervalSinceReferenceDate:(interval * -1)];

使用上述代码,订单日期为2013-10-31 02:03:20,结果日期为1988-03-03 21:56:48。

如果您尚未执行订单实体的自定义类,则需要保持此特殊订购字段为最新版本,并为订单状态和相关日期编写自定义设置器以更改此字段这取决于变化的领域。

第二种方法似乎很苛刻,需要进行非规范化,但可能是更好的解决方案,具体取决于您的应用程序以及您希望该应用程序在未来发生变化的方式。