修改@FetchRequest

Hug*_*din 5 swiftui

@FetchRequest为SwiftUI 引入了Xcode beta 5 。

我有一个视图,其中有一个@FetchRequest。将NSFetchRequest是一个管理器,使得可供财产包装自身的静态实例(不能使用自)内创建。创建时将同一实例传递给视图。

我想要的是FetchRequestself.manager.reverse.toggle()调用时进行更新,以便视图更改其对象顺序。不幸的Manager.fetchRequest()是,即使我创建新对象并在不同视图之间进行转换,它似乎也只会被调用一次,然后再也不会被调用。

我正在寻找有关如何修改使用新属性包装程序提出的提取请求的建议,以便可以根据用户操作对对象进行重新排序。

struct MainView: some View {
    @ObservedObject var manager: Manager

    @FetchRequest(fetchRequest: Manager.shared.fetchRequest())
    var ts: FetchedResults

    var body: some View {
        NavigationView {
            List(ts, id: \.self) { t in
                Text(t.name)
            }
        }.navigationBarItems(trailing:
            Button(action: { 
                self.manager.reverse.toggle() 
            }) { Text("Reverse")}
    }
}

final class Manager: ObservableObject {
    @Published var reverse: Bool = false

    // Since property wrappers cannot use self, we make a shared instance
    // available statically. This same instance is also given to the view. 
    public static let shared = Manager()

    func fetchRequest(reverse: Bool = false) -> NSFetchRequest<T> {
        let request: NSFetchRequest<T> = T.fetchRequest()

        request.sortDescriptors = [
            NSSortDescriptor(
                key: "name",
                ascending: !self.reverse
            )
        ]

        return request
    }
}
Run Code Online (Sandbox Code Playgroud)

Chu*_*k H 5

这个问题问得好!我一直在尝试做这件事和其他非常相似的事情,但收效甚微。我真的希望这个问题能在即将到来的测试版中得到合适的解决方案。但是,与此同时,可以在两个 @FetchRequests 之间切换以完成您想要做的事情。

下面是我正在处理的示例应用程序中的工作代码。我使用按钮来切换布尔@State,然后使用该状态来选择适当的@FetchResults。我不是很喜欢它,但它实际上工作得很好。

import SwiftUI
import CoreData

struct EntityListView : View {

    @Environment(\.editMode) var editMode

    @State var sortAscending: Bool = true

    @Environment(\.managedObjectContext) var context: NSManagedObjectContext

    @FetchRequest(entity: Entity.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Entity.order, ascending: true)])
    var ascendingEntities: FetchedResults<Entity>

    @FetchRequest(entity: Entity.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Entity.order, ascending: false)])
    var descendingEntities: FetchedResults<Entity>

    var body: some View {

        NavigationView {
            List() {
                Section(header: Text("All Entities".uppercased()))
                {
                    ForEach(sortAscending ? ascendingEntities : descendingEntities) { entity in

                            NavigationLink(destination: EntityEditView(entity: entity)) {

                                HStack {
                                    Text(entity.name)
                                        .font(.headline)
                                    Spacer()
                                    Text(String(entity.order))
                                        .font(.subheadline)
                                        .foregroundColor(.gray)
                                }
                            }
                            }
                            .onMove(perform: self.move)
                            .onDelete(perform: self.delete)
                }

                HStack {
                    Spacer()
                    Button(action: { self.sortAscending.toggle() }) { Text("Reverse Sort") }
                    Spacer()
                }
            }
            .listStyle(GroupedListStyle())
            .navigationBarTitle(Text("Entities"), displayMode: .large)
            .navigationBarItems(trailing: EditButton() )
        }
    }
}
Run Code Online (Sandbox Code Playgroud)