gpt4 book ai didi

ios - 在 SwiftUI 中将 @FetchRequest 与 Core Data 一起使用时修改 nil 排序行为

转载 作者:行者123 更新时间:2023-12-01 21:59:44 25 4
gpt4 key购买 nike

我在 SwiftUI 中从 Core Data 中获取实体,并希望像这样对它们进行排序:

  • 如果有下一个日期,按升序排序
  • 在那些有下一个日期的下方,按创建日期排序剩余的

  • 我有:
    @FetchRequest(entity: MyEntity.entity(), sortDescriptors: [
    NSSortDescriptor(keyPath: \MyEntity.nextDate, ascending: true),
    NSSortDescriptor(keyPath: \MyEntity.dateCreated, ascending: true)
    ]) private var entities: FetchedResults<MyEntity>

    问题是那些没有下一个日期的都排在那些有非零下一个日期的上面,如 other question 所示。 .

    我试图继承 NSSortDescriptor搬家 nil值到最后,但它从不调用任何被覆盖的函数。
    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)
    }
    }

    我也尝试使用 NSSortDescriptor包含比较器 block 的 API,但是这会崩溃

    Exception: "unsupported NSSortDescriptor (comparator blocks are not supported)"



    我怎样才能实现所需的排序行为?

    最佳答案

    @FetchRequest 使用排序描述符作为获取请求的一部分,因此您不能在获取请求的定义中使用比较器 block (至少,不能使用 SQLite 存储)。但是,您可以对获取的结果(entities)进行排序,作为 body 处理的一部分。 View ,使用 sorted(by:) :

    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...
    ...
    }
    }
    }
    }

    为简单起见,我假设 dateCreated是非可选的。如果不是,您将需要修改排序谓词以处理 nil 值。它也可能写得更漂亮——但我希望你能明白。

    只是要注意它在内存中排序,因此不知道此解决方案的性能和/或内存影响。

    关于ios - 在 SwiftUI 中将 @FetchRequest 与 Core Data 一起使用时修改 nil 排序行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60365910/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com