按最近的日期忽略年份对NSFetchedResultsController进行排序

时间:2015-10-26 17:57:57

标签: ios swift core-data nsdate nsfetchedresultscontroller

我正在使用Core Data和NSFetchedResultsController在表视图中显示日期。在获取时,我希望这些日期对象按照最接近的即将到来的月/日排序,而忽略年份,最好(如果可能),而不必将获取的结果存储在数组中,并强制对该数组执行单独的排序操作。这是基本想法,其余的是背景。​​

我的NSManagedObject子类Date有2个属性:

Date.date -> 1986-02-06 08:00:00 +0000 // the stored date of type Date
Date.equalizedDate -> 02/06 // computed from date ignoring year of type String

如果我在获取的结果控制器上使用NSSortDescriptor(key: "date", ascending: true),那么表格视图中的日期按年份排序(不是我想要的):

Date.date 1978-06-23 07:00:00 +0000 // 1978 = #1
Date.date 1986-02-06 08:00:00 +0000 // 1986 = #2
Date.date 1991-07-26 07:00:00 +0000 // 1991 = #3

如果我使用NSSortDescriptor(key: "equalizedDate", ascending: true)我可以通过忽略年份并显示适当的提升而更近一步但是它与今天的日期不相符:

Date.date 1986-02-06 08:00:00 +0000 // 02/06 = #1 (February 6th)
Date.date 1978-06-23 07:00:00 +0000 // 06/23 = #2 (June 23rd)
Date.date 1991-07-26 07:00:00 +0000 // 07/26 = #3 (July 26th)

例如,如果今天是4月5日,那么我希望获取并显示获取的结果,如下所示:

                                       // Today is April 5th
Date.date 1978-06-23 07:00:00 +0000 // 06/23 = #1 (June 23rd)
Date.date 1991-07-26 07:00:00 +0000 // 07/26 = #2 (July 26th)
Date.date 1986-02-06 08:00:00 +0000 // 02/06 = #3 (February 6th)

目前,我实现这一目标的唯一方法是将获取的结果控制器结果存储在数组中,对数组执行比较,并使用数组而不是我的获取结果控制器作为表视图的数据源行和单元格:

// fetchedResults = [Date] <- stored Date objects from fetch
for fetchedDate in fetchedResults {
    // formatDateIntoString changes 2015-10-26 05:43:22 +0000 into 10/26
    if fetchedDate.equalizedDate < NSDate().formatDateIntoString() {
        fetchedResults.removeAtIndex(0)
        fetchedResults.append(fetchedDate)
    } else {
        break
    }
}
return fetchedResults

我宁愿省略这个额外的逻辑层,因为它不仅消除了获取结果控制器性能的全部目的,而且在实现滑动删除时也给了我不可思议的麻烦和错误的索引路径(link for reference )。我知道比较器和选择器不适用于获取的结果控制器。

有没有办法解决这个问题?

2 个答案:

答案 0 :(得分:2)

如果您不关心部分,一个简单的方法是保持您对equalizedDate的排序(如果您有很多日期,请确保将该属性设置为索引)。您可能还想考虑将其更改为整数而不是字符串。

阵列将从01/01到12/31排序。

然后,您可以在初始提取后再进行一次快速提取,以找到最接近今天日期的对象。

该对象现在成为您的参考点(或startingIndex)。

在FRC委托中,只需使用起始索引作为偏移量。

因此,当要求在索引0处返回objet时,您将根据起始索引返回一个值。

类似......

NSUInteger actualIndex = (index + startingIndex) % count;

如果你使用的是部分,那会有点复杂,但并不多。

这样,您无需为排序做任何特殊操作。当应用程序中的日期发生变化时,也可以轻松更改。

答案 1 :(得分:1)

我认为更简单的解决方案是简单地修改您的equalizedDate属性,如下所示:

首先,将其变为瞬态属性。

其次,根据当前日期使其动态行为。您可以使此属性非常简单,但是需要编写更多代码来解释它,或者您可以尝试返回可以直接使用的内容。

一个简单的解决方案是仅返回今天日期的偏移量(一个从0到365的数字)。您必须添加功能以基于此数字和今天的日期返回正确的日期字符串(或日期)。

IMO更好的解决方案是返回正确规范化年份的日期。您可以将当前和未来日期设置为当前年份,将所有过去日期设置为下一年,同时生成365(366)个日期。

您现在可以通过瞬态属性轻松排序,甚至可以将其用于切片。