【发布时间】:2022-01-26 19:17:22
【问题描述】:
通过使用核心数据构建应用来学习 swiftui;陷入从 Detail 到 AddEdit 的 Edit 的数据流问题;从 AddEdit 到 List 以及从 List 到 Detail 的流程都可以。在网上搜索但没有找到有用的信息,或者我不明白。这是该问题的简化项目。它在 13.2 测试版上符合要求,并且可以在模拟器上运行,但存在来自 Detail 的空白编辑视图的问题。
观看次数:
struct FileList: View {
@FetchRequest(sortDescriptors: [ NSSortDescriptor(keyPath: \Item.fileName, ascending: false) ], animation: .default) var items: FetchedResults<Item>
@State private var showAdd = false
var body: some View {
NavigationView {
List {
ForEach(items) { item in
NavigationLink(destination: FileDetail(item: item)) {
Text(item.fileName ?? "").font(.headline)
}
}
}
.navigationTitle("List")
.navigationBarItems(trailing: Button(action: {
showAdd = true
}, label: { Image(systemName: "plus.circle")
})
.sheet(isPresented: $showAdd) {
FileAddEdit(items: VM())
}
)
}
}
}
struct FileList_Previews: PreviewProvider {
static let context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
static var previews: some View {
FileList()
}
}
struct FileDetail: View {
@Environment(\.managedObjectContext) var context
@Environment(\.presentationMode) var presentationMode
@State var showingEdit = false
@ObservedObject var item: Item
var body: some View {
VStack {
Form {
Text(self.item.fileName ?? "File Name")
Button(action: {
showingEdit.toggle()
}, label: {
title: do { Text("Edit")
}
})
.sheet(isPresented: $showingEdit) {
FileAddEdit(items: VM())
}
}
}.navigationTitle("Detail")
}
}
struct FileDetails_Previews: PreviewProvider {
static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
static var previews: some View {
let item = Item(context: moc)
return NavigationView {
FileDetail(item: item)
}
}
}
struct FileAddEdit: View {
@Environment(\.managedObjectContext) var moc
@ObservedObject var items = VM()
var body: some View {
NavigationView {
VStack {
Form {
TextField("File Name", text: $items.fileName)
Button(action: {
items.writeData(context: moc)
}, label: {
title: do { Text(items.updateFile == nil ? "Add" : "Edit")
}})
}
}
.navigationTitle("\(items.updateFile == nil ? "Add" : "Edit")")
}
}
}
struct FileAddEdit_Previews: PreviewProvider {
static var previews: some View {
FileAddEdit(items: VM())
}
}
虚拟机:
class VM: ObservableObject {
@Published var fileName = ""
@Published var id = UUID()
@Published var isNewData = false
@Published var updateFile : Item!
init() {
}
var temporaryStorage: [String] = []
func writeData(context : NSManagedObjectContext) {
if updateFile != nil {
updateCurrentFile()
} else {
createNewFile(context: context)
}
do {
try context.save()
} catch {
print(error.localizedDescription)
}
}
func DetailItem(fileItem: Item){
fileName = fileItem.fileName ?? ""
id = fileItem.id ?? UUID()
updateFile = fileItem
}
func EditItem(fileItem: Item){
fileName = fileItem.fileName ?? ""
id = fileItem.id ?? UUID()
isNewData.toggle()
updateFile = fileItem
}
private func createNewFile(context : NSManagedObjectContext) {
let newFile = Item(context: context)
newFile.fileName = fileName
newFile.id = id
}
private func updateCurrentFile() {
updateFile.fileName = fileName
updateFile.id = id
}
private func resetData() {
fileName = ""
id = UUID()
isNewData.toggle()
updateFile = nil
}
}
非常感谢您的宝贵时间和建议!
【问题讨论】:
-
所有 coredata 对象都是 ObservableObjects,所以只需将所有 FileEnt 包装在 @ObservedObject 中,这样您就可以看到更改并对其进行编辑。
-
用简化的视图/VM 重新发布(FileEnt 被替换为 Item)。我不知道的是如何使用 ObservableObjects 使 .sheet in Detail 将 Detail 数据包装到 AddEdit。希望你能点亮更多的灯。谢谢。
标签: core-data swiftui-navigationlink detailview