ios - 对 SwiftUI FetchRequest 的更改不会触发视图刷新?
问题描述
使用 FetchRequest 包装器,并在视图内更改获取结果的数据。这在第一次加载视图时有效,每次更改都会更新视图..
问题是如果我离开视图并再次返回,获取请求数据的更改将停止刷新视图。查看更改的唯一方法是再次导航离开并返回。
我正在打印获取请求,并且对数据的更改正在工作,这解释了为什么如果我再次导航回来,视图会正确显示,但是当视图上的数据发生更改时视图不会刷新。
这是一个错误还是我做错了什么?
我有一个显示所有期刊的图书馆视图,第一部分是一个允许添加新期刊的文本字段,第二部分是所有期刊的列表,可以选择它们旁边的复选标记。
添加新期刊并第一次选择它们就可以了。很奇怪,如果我离开并回来,它们就会停止工作。
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") }
}
}
我已经尝试从导航栏项目中删除导航链接,并将其用作标准列表行导航链接,结果是相同的。
解决方案
有同样的问题。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()))
推荐阅读
- web-services - 使用 SSIS 中的 Web 服务脚本任务定期触发 Web 服务
- c# - 如何捕获取消长时间运行的延迟 DTF 自定义操作?
- typescript - 打字稿联合类型 - 数组 forEach 错误
- sql-server - DAX 时间智能函数 - 性能数据计算
- java - 将背景图像设置为标题单元格
- mysql - 创建mysql存储过程时出现1193错误
- c# - 重构类以使其可注入/可模拟
- tensorflow - Google Colab TPU 比 GPU 需要更多时间
- internet-explorer - JAWS 不读取 IE 11 中的警报
- android - Gradle 同步失败:原因:com.android.builder.errors.EvalIssueReporter