Ios 在SwiftUI中将@FetchRequest与核心数据一起使用时修改nil排序行为
我正在从SwiftUI中的核心数据中提取实体,并希望按如下方式对它们进行排序:Ios 在SwiftUI中将@FetchRequest与核心数据一起使用时修改nil排序行为,ios,swift,core-data,swiftui,Ios,Swift,Core Data,Swiftui,我正在从SwiftUI中的核心数据中提取实体,并希望按如下方式对它们进行排序: 如果有下一个日期,按升序排序 在那些有下一个日期的下面,按创建的日期对剩余的进行排序 我有: @FetchRequest(entity: MyEntity.entity(), sortDescriptors: [ NSSortDescriptor(keyPath: \MyEntity.nextDate, ascending: true), NSSortDescriptor(keyPath: \MyEn
@FetchRequest(entity: MyEntity.entity(), sortDescriptors: [
NSSortDescriptor(keyPath: \MyEntity.nextDate, ascending: true),
NSSortDescriptor(keyPath: \MyEntity.dateCreated, ascending: true)
]) private var entities: FetchedResults<MyEntity>
我还尝试使用包含比较器块的NSSortDescriptor
API,但是这会与
异常:“不支持的NSSortDescriptor(不支持比较器块
支持的“
如何实现所需的排序行为?在CoreData中,排序仅使用NSString类中的方法,如“compare:”或“localizedStandardCompare:”之类的方法
由于您无法重写这些方法,甚至在大多数情况下都无法更改它们,所以您可以考虑其他解决方案。 您可以设置一个
特殊日期,而不是“Nil”日期,如果所需数据为“Nil”,该日期将非常晚。通过这种方式,您可以将这些日期排序到底部。
您不能显示这些特殊日期,也不能在SwiftView中将其显示为“无”
您可以只玩NSString
游戏,而不是子类
。@FetchRequest使用排序描述符作为fetch请求的一部分,因此您不能在fetch请求的定义中使用比较器块(至少不能与SQLite存储一起使用)。但是,在处理视图的主体
的过程中,可以使用以下方法对提取(实体
)的结果进行排序:
var主体:一些视图{
VStack{
名单{
ForEach(self.entities.sorted)(按:{first,second in.)
如果first.nextDate==nil&&second.nextDate==nil{return(first.dateCreated)显示如何在@FetchRequest中调用子类NSSortDescriptor,please@E.Coms更新
final class NilsLastSortDescriptor: NSSortDescriptor {
override func copy(with zone: NSZone? = nil) -> Any {
return NilsLastSortDescriptor(key: self.key, ascending: self.ascending, selector: self.selector)
}
override var reversedSortDescriptor: Any {
return NilsLastSortDescriptor(key: self.key, ascending: !self.ascending, selector: self.selector)
}
override func compare(_ object1: Any, to object2: Any) -> ComparisonResult {
if (object1 as AnyObject).value(forKey: self.key!) == nil && (object2 as AnyObject).value(forKey: self.key!) == nil {
return .orderedSame
}
if (object1 as AnyObject).value(forKey: self.key!) == nil {
return .orderedDescending
}
if (object2 as AnyObject).value(forKey: self.key!) == nil {
return .orderedAscending
}
return super.compare(object1, to: object2)
}
}
var body: some View {
VStack {
List{
ForEach(self.entities.sorted(by: { first, second in
if first.nextDate == nil && second.nextDate == nil { return (first.dateCreated <= second.dateCreated) }
if first.nextDate == nil { return false }
if second.nextDate == nil { return true }
if first.nextDate! == second.nextDate! { return (first.dateCreated <= second.dateCreated) }
return (first.nextDate! < second.nextDate!)
}), id: \.self) { myEntity in
// Your code for your cells...
...
}
}
}
}