微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

@FetchRequest

如何解决@FetchRequest

我有一个列表,其中包含标题和日期。用户可以设置要排序的内容标题或日期)。

但是我不知道如何动态更改NSSortDescriptor。

import SwiftUI
import CoreData

struct ContentView: View {
    @Environment(\.managedobjectContext) private var viewContext

    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Test.title,ascending: true)],animation: .default) private var items: FetchedResults<Test>

    @State private var sortType: Int = 0
    @State private var sortDescriptor: NSSortDescriptor = NSSortDescriptor(keyPath: \Test.title,ascending: true)

    var body: some View {
        Picker(selection: $sortType,label: Text("Sort")) {
            Text("Title").tag(0)
            Text("Date").tag(1)
        }
        .pickerStyle(SegmentedPickerStyle())
        .onChange(of: sortType) { value in
            sortType = value

            if sortType == 0 {
                sortDescriptor = NSSortDescriptor(keyPath: \Test.title,ascending: true)
            } else {
                sortDescriptor = NSSortDescriptor(keyPath: \Test.date,ascending: true)
            }
        }

        List {
            ForEach(items) { item in
                let dateString = itemFormatter.string(from: item.date!)
                HStack {
                    Text(item.title!)
                    Spacer()
                    Text(dateString)
                }
            }
        }

        .onAppear(perform: {
            if items.isEmpty {
                let newEntry1 = Test(context: self.viewContext)
                newEntry1.title = "Apple"
                newEntry1.date = Date(timeIntervalSince1970: 197200800)

                let newEntry2 = Test(context: self.viewContext)
                newEntry2.title = "Microsoft"
                newEntry2.date = Date(timeIntervalSince1970: 168429600)

                let newEntry3 = Test(context: self.viewContext)
                newEntry3.title = "Google"
                newEntry3.date = Date(timeIntervalSince1970: 904903200)

                let newEntry4 = Test(context: self.viewContext)
                newEntry4.title = "Amazon"
                newEntry4.date = Date(timeIntervalSince1970: 773402400)

                if self.viewContext.hasChanges {
                    try? self.viewContext.save()
                }
            }
        })
    }
}

private let itemFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateStyle = .short
    formatter.timeStyle = .none
    return formatter
}()

当我改变

@FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Test.title,animation: .default) private var items: FetchedResults<Test>

@FetchRequest(sortDescriptors: [sortDescriptor],animation: .default) private var items: FetchedResults<Test>

出现错误“无法在属性初始化程序中使用实例成员'sortDescriptor';属性初始化程序在'self'可用之前运行”。

我还尝试将NSSortDescriptor存储在UserDefault中,并创建一个创建它自己的FetchRequest的init。.仍然没有动态排序...

有人找到解决该问题的指针了吗?

在这里找到了整个项目:https://github.com/l1ghthouse/FRDSD

解决方法

解决了!感谢Asperi指出此质量检查:https://stackoverflow.com/a/59345830/12299030

import SwiftUI
import CoreData

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext

    @AppStorage("firstLaunch") var firstLaunch: Bool = true
    @State var sortDescriptor: NSSortDescriptor = NSSortDescriptor(keyPath: \Test.title,ascending: true)
    @State private var sortType: Int = 0

    var body: some View {
        Picker(selection: $sortType,label: Text("Sort")) {
            Text("Title").tag(0)
            Text("Date").tag(1)
        }
        .pickerStyle(SegmentedPickerStyle())
        .onChange(of: sortType) { value in
            sortType = value

            if sortType == 0 {
                sortDescriptor = NSSortDescriptor(keyPath: \Test.title,ascending: true)
            } else {
                sortDescriptor = NSSortDescriptor(keyPath: \Test.date,ascending: true)
            }
        }

        ListView(sortDescripter: sortDescriptor)

        .onAppear(perform: {
            if firstLaunch == true {
                let newEntry1 = Test(context: self.viewContext)
                newEntry1.title = "Apple"
                newEntry1.date = Date(timeIntervalSince1970: 197200800)

                let newEntry2 = Test(context: self.viewContext)
                newEntry2.title = "Microsoft"
                newEntry2.date = Date(timeIntervalSince1970: 168429600)

                let newEntry3 = Test(context: self.viewContext)
                newEntry3.title = "Google"
                newEntry3.date = Date(timeIntervalSince1970: 904903200)

                let newEntry4 = Test(context: self.viewContext)
                newEntry4.title = "Amazon"
                newEntry4.date = Date(timeIntervalSince1970: 773402400)

                if self.viewContext.hasChanges {
                    try? self.viewContext.save()
                }

                firstLaunch = false
            }
        })
    }
}

struct ListView: View {
    @FetchRequest var items: FetchedResults<Test>
    @Environment(\.managedObjectContext) var viewContext

    init(sortDescripter: NSSortDescriptor) {
        let request: NSFetchRequest<Test> = Test.fetchRequest()
        request.sortDescriptors = [sortDescripter]
        _items = FetchRequest<Test>(fetchRequest: request)
    }

    var body: some View {
        List {
            ForEach(items) { item in
                let dateString = itemFormatter.string(from: item.date!)
                HStack {
                    Text(item.title!)
                    Spacer()
                    Text(dateString)
                }
            }
        }
    }
}

private let itemFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateStyle = .short
    formatter.timeStyle = .none
    return formatter
}()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?