NSFetchedResultsController对不同的部分进行不同的排序(升序/降序)?

时间:2020-12-04 15:08:20

In my app, I have a task list (no, it's not just another todo app), and I display the tasks in a UITableView using an NSFetchedResultsController. Here is the relevant initialisation code:

在我的应用程序中,我有一个任务列表(不,它不只是另一个todo应用程序),我使用NSFetchedResultsController在UITableView中显示任务。以下是相关的初始化代码:

NSSortDescriptor *dueDateSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"due" YES];
NSSortDescriptor *completionSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"completed" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:completionSortDescriptor, dueDateSortDescriptor, nil]];

_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@"completed" cacheName:nil];

What this does is sorts the tasks such that I have an incomplete tasks section at the top, sorting with the tasks due first on top, and tasks due later further down. This all works.

它所做的是对任务进行排序,使我在顶部有一个不完整的任务部分,将首先要处理的任务排序在顶部,然后是后面的任务排序。这一切工作。

However, this means that the second section, the one with the completed tasks, also sorts this way, so the earliest due tasks are on top. What I want to do is change it so the second section sorts the other way around (in descending order), but the first section stays sorted in ascending order. Is this even possible? How would I go about this?

然而,这意味着第二部分(包含已完成任务的部分)也以这种方式进行排序,所以最早的到期任务在上面。我要做的是改变它,所以第二部分用另一种方式排序(按降序排序),但是第一部分按升序排序。这是可能吗?我该怎么做呢?

Why I want to do this: The way it currently works, the tasks at the top of the second section (and therefore the most visible) are the ones that were completed ages ago. It is more likely that the user would want to see the tasks that are more recently completed (and uncheck one if it was accidentally checked), and presumably the tasks with a more recent due date were more recently completed. I am happy to add a separate completion date field to the Core Data task object if necessary (This isn't a shipping application yet, so I can change the data format however I like).

为什么我要这样做:它当前的工作方式,第二部分顶部的任务(因此是最明显的)是在很久以前完成的。更有可能的是,用户希望看到最近完成的任务(如果不小心检查的话,就取消检查),而且最近到期的任务可能更接近于最近完成的任务。如果需要的话,我很乐意在Core Data任务对象中添加一个单独的完成日期字段(这还不是一个发布应用程序,所以我可以随意更改数据格式)。

1 个解决方案

#1


3  

This is not possible when using an NSFetchedResultsController. You'd have to manually fetch your data and implement UITableView's delegate methods.

这在使用NSFetchedResultsController时是不可能的。您必须手动获取数据并实现UITableView的委托方法。

EDIT: Whoah, my mistake, there's a fairly easy solution for this. Set two sort descriptors:

编辑:哦,我的错误,有一个很简单的解决方法。设置两个描述符:

  • The first one for completedDate (descending). This field is the same (nil) for all incomplete tasks.

    第一个完整的(降序)。此字段对于所有不完整的任务都是相同的(nil)。

  • Add a second one for addedDate (ascending). It will sort by completed date (newest first), but in the first section you won't have any completedDates, so it will then use the added date (oldest first).

    添加第二个addedDate(升序)。它将按完成的日期(最新的日期)排序,但是在第一部分中,您将没有任何完整的日期,因此它将使用添加的日期(最早的日期)。

For the second section, it will just use completedDate (newest first), so there you go.

对于第二部分,它将使用completedDate(最新的第一个),所以就这样了。

#1


3  

This is not possible when using an NSFetchedResultsController. You'd have to manually fetch your data and implement UITableView's delegate methods.

这在使用NSFetchedResultsController时是不可能的。您必须手动获取数据并实现UITableView的委托方法。

EDIT: Whoah, my mistake, there's a fairly easy solution for this. Set two sort descriptors:

编辑:哦,我的错误,有一个很简单的解决方法。设置两个描述符:

  • The first one for completedDate (descending). This field is the same (nil) for all incomplete tasks.

    第一个完整的(降序)。此字段对于所有不完整的任务都是相同的(nil)。

  • Add a second one for addedDate (ascending). It will sort by completed date (newest first), but in the first section you won't have any completedDates, so it will then use the added date (oldest first).

    添加第二个addedDate(升序)。它将按完成的日期(最新的日期)排序,但是在第一部分中,您将没有任何完整的日期,因此它将使用添加的日期(最早的日期)。

For the second section, it will just use completedDate (newest first), so there you go.

对于第二部分,它将使用completedDate(最新的第一个),所以就这样了。