对SwiftUI FetchRequest的更改不会触发视图刷新?

时间:2019-10-12 18:49:56

标签: ios swift swiftui

使用FetchRequest包装器,并在视图内部更改获取结果的数据。第一次加载视图时,此方法有效,视图会随着所做的每一次更改进行更新。

问题是,如果我离开视图并再次返回,则对获取请求数据的更改将停止刷新视图。查看更改的唯一方法是导航并再次返回。

我正在打印获取请求,并且对数据所做的更改正在工作,这说明了为什么如果我再次导航回去,视图将正确显示,但是当视图上的数据更改时,视图没有刷新。

这是错误还是我做错了什么?

我有一个显示所有日记的库视图,第一部分是允许添加新日记的文本字段,第二部分是可以选择以在其旁边打勾的所有日记的列表。 / p>

第一次添加新日记并选择它们是可行的。非常奇怪的是,如果我离开并返回,它们将停止工作。


struct LibraryView: View {

    // MARK: - PROPERTIES
    @Environment(\.managedObjectContext) var context


    @FetchRequest(
      //  entity: Journal.entity(),
        sortDescriptors: [NSSortDescriptor(keyPath: \Journal.name, ascending: true)],
        animation: .default
    ) var journals: FetchedResults<Journal>


    @State private var name = ""


    // MARK: - INITIAL VIEW -
    var body: some View {

        Form {

            Section(header: Text("New Journal")) {
                HStack {

                    TextField("Name", text: $name, onCommit: {
                        let newJournal = Journal(context: self.context)
                        newJournal.name = self.name
                        try? self.context.save()
                        self.name = ""
                    })

                    Button(action: { print("ACTION") }) {
                        Image(systemName: "plus.circle.fill")
                    }
                }
            }

            Section(header: Text("Journals")) {
                ForEach(journals) { journal in
                    Button(action: {
                        journal.isSelected.toggle()
                        try? self.context.save()

                    }) {
                        HStack {
                            Text(journal.name)
                            Spacer()
                            if journal.isSelected {
                                Image(systemName: "circle.fill")
                            }
                        }
                    }
                }
            }

        }.navigationBarTitle("Library")
    }
}

日志只是一个简单的核心数据模型:


import Foundation
import CoreData

public class Journal: NSManagedObject, Identifiable {

    @NSManaged public var name: String
    @NSManaged public var isSelected: Bool

}

我从带有导航栏中导航链接的选项卡视图导航到图书馆视图:


struct JournalView: View {

    // MARK: - PROPERTIES
    @State private var presentFiltersView = false

    // MARK: - INITIAL VIEW -
    var body: some View {
        NavigationView {
            Text("Journal")
                .navigationBarTitle("Journal")
                .navigationBarItems(
                    leading: NavigationLink(destination: LibraryView()) {
                        Text("Library")
                    },
                    trailing: Button(action: { self.presentFiltersView = true }) {
                        Text("Filters")
                    })
        }.sheet(isPresented: $presentFiltersView) { Text("Filters") }
    }
}

我尝试从导航栏项中删除导航链接,并将其用作标准列表行导航链接,结果是相同的。

3 个答案:

答案 0 :(得分:4)

一个很好的问题,我碰巧也遇到同样的问题。一个简单的.onAppear()会有所帮助,但是我不知道如何.update()新的@FetchRequest。

答案 1 :(得分:2)

有同样的问题。 NavigationLink立即实例化目标视图。一旦将其更改为惰性视图评估,它将开始为我工作。但这看起来仍然是解决方法。

struct LazyView<Content: View>: View {
    let build: () -> Content
    init(_ build: @autoclosure @escaping () -> Content) {
        self.build = build
    }
    var body: Content {
        build()
    }
}

请参阅:https://www.objc.io/blog/2019/07/02/lazy-loading/

NavigationLink(destination: LazyView(LibraryView()))

答案 2 :(得分:1)

想想我为什么会这样。问题是我导航到视图的方式。原因是导航栏项中有导航链接。取而代之的是,我自己将导航链接移到了外面,并用一个控制导航链接的活动状态的按钮替换了它。提取请求现在似乎可以正常工作。

之前:

.navigationBarItems(leading:
    NavigationLink(
        destination: MyView(),
        label: {
    Text("MyView")
}))

之后:

NavigationLink(
    destination: MyView(),
    isActive: $isActive,
    label: {
        EmptyView()
})

.navigationBarItems(leading:
    Button(
        action: self.isActive = true,
        label: {
    Text("My View")
}))