在 NSSortDescriptor 中排序(今天之前或之后)
Sort on (before or after today) in NSSortDescriptor
我有一个 NSFetchedResultsController
为 UITableViewController
提供 Appointment
个实体,其中有 属性 dateTime
.
我的目标是按如下方式排序约会列表:
- 今天
- 明天
- 后天
- 昨天
- 前天
换句话说:
先排序是在今天之前还是之后,然后是 dateTime
。因此,首先对 (dateTime > %TODAY%)
进行排序,然后对 dateTime
本身进行排序(未来升序,过去降序)。
有什么办法吗?我的问题是我不能在排序描述符中使用 %TODAY%,但也许有另一种方法可以实现相同的视觉效果。
更新:请注意 NSFetchedResultsController
无法接受已接受的答案。我选择了另一个解决方案,在显示视图之前订购 Appointments
,将其保存到数据库,然后让 NSFetchedResultsController
获取更改。
更新 2:
接受的答案确实完全符合我的要求。我的实施:
let futureAppointments = appointments.filter({ [=10=].dateTime != nil && [=10=].dateTime?.compare(Date()) == .orderedDescending })
.sorted(by: { [=10=].dateTime?.compare(.dateTime! as Date) == .orderedAscending })
let pastAppointments = appointments.filter({ [=10=].dateTime != nil && [=10=].dateTime?.compare(Date()) == .orderedAscending })
.sorted(by: { [=10=].dateTime?.compare(.dateTime! as Date) == .orderedDescending })
let sorted = futureAppointments + pastAppointments
for (index, appointment) in sorted.enumerated() {
appointment.order = NSNumber(integerLiteral: index)
}
使用两个 fetchedResultsControllers,一个使用谓词升序排序,排除今天之前创建的那些,另一个使用谓词降序排序,排除未来约会。
编写一个函数在fetchedResultsController indexPath 和tableview 的indexPath 之间进行转换,反之亦然。只需确保跟踪您正在处理的 indexPath 类型,这并不难。
这只是想法。也许您可以像这样创建 sortdescriptor:
NSSortDescriptor(key: "test", ascending: true) { (v1, v2) -> ComparisonResult in
guard let d1 = v1 as? Date else
{
return .orderedAscending
}
guard let d2 = v2 as? Date else
{
return .orderedAscending
}
if abs(d1.timeIntervalSinceNow) < abs(d2.timeIntervalSinceNow) { return .orderedAscending }
if abs(d1.timeIntervalSinceNow) > abs(d2.timeIntervalSinceNow) { return .orderedDescending }
return .orderedSame
}
我认为这会奏效。
我有一个 NSFetchedResultsController
为 UITableViewController
提供 Appointment
个实体,其中有 属性 dateTime
.
我的目标是按如下方式排序约会列表:
- 今天
- 明天
- 后天
- 昨天
- 前天
换句话说:
先排序是在今天之前还是之后,然后是 dateTime
。因此,首先对 (dateTime > %TODAY%)
进行排序,然后对 dateTime
本身进行排序(未来升序,过去降序)。
有什么办法吗?我的问题是我不能在排序描述符中使用 %TODAY%,但也许有另一种方法可以实现相同的视觉效果。
更新:请注意 NSFetchedResultsController
无法接受已接受的答案。我选择了另一个解决方案,在显示视图之前订购 Appointments
,将其保存到数据库,然后让 NSFetchedResultsController
获取更改。
更新 2: 接受的答案确实完全符合我的要求。我的实施:
let futureAppointments = appointments.filter({ [=10=].dateTime != nil && [=10=].dateTime?.compare(Date()) == .orderedDescending })
.sorted(by: { [=10=].dateTime?.compare(.dateTime! as Date) == .orderedAscending })
let pastAppointments = appointments.filter({ [=10=].dateTime != nil && [=10=].dateTime?.compare(Date()) == .orderedAscending })
.sorted(by: { [=10=].dateTime?.compare(.dateTime! as Date) == .orderedDescending })
let sorted = futureAppointments + pastAppointments
for (index, appointment) in sorted.enumerated() {
appointment.order = NSNumber(integerLiteral: index)
}
使用两个 fetchedResultsControllers,一个使用谓词升序排序,排除今天之前创建的那些,另一个使用谓词降序排序,排除未来约会。
编写一个函数在fetchedResultsController indexPath 和tableview 的indexPath 之间进行转换,反之亦然。只需确保跟踪您正在处理的 indexPath 类型,这并不难。
这只是想法。也许您可以像这样创建 sortdescriptor:
NSSortDescriptor(key: "test", ascending: true) { (v1, v2) -> ComparisonResult in
guard let d1 = v1 as? Date else
{
return .orderedAscending
}
guard let d2 = v2 as? Date else
{
return .orderedAscending
}
if abs(d1.timeIntervalSinceNow) < abs(d2.timeIntervalSinceNow) { return .orderedAscending }
if abs(d1.timeIntervalSinceNow) > abs(d2.timeIntervalSinceNow) { return .orderedDescending }
return .orderedSame
}
我认为这会奏效。