简体   繁体   English

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

[英]UITableView with NSFetchedResultsController: Sort each section independently of each other

I'm developing a Core Data Application. 我正在开发核心数据应用程序。 I have a main table that displays Orders with different Statuses: New, Accepted, Delivered, etc. 我有一个主表,显示具有不同状态的订单:新建,已接受,已交付等。

The problem I'm having is that I need to order each section by differently Criteria. 我遇到的问题是我需要通过不同的Criteria订购每个部分。 For example: 例如:

  • New orders need to be sorted by the oldest on top. 新订单需要按最旧的订单排序。
  • Accepted orders need to be sorted by soonest to deliver on top. 接受的订单需要通过最快的方式进行排序。
  • Delivered orders need to be sorted by newest on top. 交付的订单需要按最新排序。

So this is the code that I have now when fetching results: 所以这是我在获取结果时的代码:

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

As you can see, this is making sections based on "orderPosition" and ordering all the orders by "createdDate" . 正如你所看到的,这是基于使部分"orderPosition" ,并下令所有的订单"createdDate" But I need to order certain orders by "deliverDate" 但我需要通过"deliverDate"订购某些订单

Thanks 谢谢

I can think of two ways around this problem. 我可以想出解决这个问题的两种方法。

Method One: Use a separate NSFetchedResultsController for each section. 方法一:为每个部分使用单独的NSFetchedResultsController。 This way you can use a different search descriptor for each section. 这样,您可以为每个部分使用不同的搜索描述符。 This ties some of the model details to your controller and means that if you plan to create a new status type you will need to modify your controller as well as your model. 这将一些模型细节与您的控制器联系起来,这意味着如果您计划创建新的状态类型,则需要修改控制器和模型。

The simplest way to implement this is to create an array of the different NSFetchedResultsControllers. 实现此目的的最简单方法是创建不同NSFetchedResultsControllers的数组。 The number of items in the array is the number of sections. 数组中的项目数是节数。 Note, however, that doing this might result in empty sections in your table view. 但请注意,这样做可能会导致表视图中出现空白部分。 For example, if there aren't any accepted orders, you will probably still end up with the Accepted Orders section in your UITableView. 例如,如果没有任何已接受的订单,您可能仍会在UITableView中找到“接受的订单”部分。

At a certain point, this can get complicated enough to warrant putting this code into its own custom results controller that manages a list of NSFetchedResultsControllers internally and expose an external interface similar or identical to an NSFetchedResultsController. 在某个时刻,这可能变得足够复杂以保证将此代码放入其自己的自定义结果控制器中,该控制器在内部管理NSFetchedResultsControllers列表并公开与NSFetchedResultsController类似或相同的外部接口。

Method Two: Add a special field your model to use as a sort field then automatically update that field to keep the sort order the way you like it. 方法二:添加模型的特殊字段以用作排序字段,然后自动更新该字段以按照您喜欢的方式保持排序顺序。 For example, for orders with a status "new" you just store the order date in this field. 例如,对于状态为“新”的订单,您只需将订单日期存储在此字段中。 For orders with the "accepted" status, you store the delivery date. 对于具有“已接受”状态的订单,您可以存储交货日期。 For orders with the "delivered" status, you want to store the order date, but you want it to be in a reverse direction. 对于具有“已交付”状态的订单,您希望存储订单日期,但您希望它处于反方向。 The simplest way to implement this reversal in order is to store the order date multiplied by -1. 按顺序实现此反转的最简单方法是将订单日期存储乘以-1。

NSDate's are just wrappers around a simple primitive which stores the time interval between the represented date and January 1st, 2001. You can easily multiply that number by -1 using this code: NSDate只是一个简单原语的包装器,它存储了所表示日期和2001年1月1日之间的时间间隔。您可以使用以下代码轻松地将该数字乘以-1:

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

Using the above code, an order date of 2013-10-31 02:03:20 results in a reversed date of 1988-03-03 21:56:48. 使用上述代码,订单日期为2013-10-31 02:03:20,结果日期为1988-03-03 21:56:48。

You will need to keep this special ordering field up to date by implementing a custom class for the Order entity if you haven't done so already, and writing custom setters for the order status and the dates involved to change this field when the fields it depends on change. 您需要通过为Order实体实现自定义类(如果尚未执行此操作)来保持此特殊排序字段是最新的,并为订单状态和所涉及的日期编写自定义setter以更改此字段取决于变化。

This second method seems hakish and entails denormalization but may be the better solution depending on your application and how you expect that application to change in the future. 第二种方法似乎很苛刻,需要非规范化,但可能是更好的解决方案,具体取决于您的应用程序以及您希望该应用程序在未来发生变化的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM