【问题标题】:SwiftUI: How to Save value from a TextField in core dataSwiftUI:如何从核心数据中的 TextField 中保存值
【发布时间】:2020-02-15 21:44:42
【问题描述】:

我正在按照教程构建一个非常简单的 SwiftUI 应用程序。 我创建了一个包含从 CoreData @fetched 的项目列表的视图,并且列表显示没有问题。 然后我添加了一个带有TextFieldButton 的模态窗口来保存数据。 这是模态的代码:

import SwiftUI

struct AddCategoryView: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    @Environment(\.managedObjectContext) var context

    @State public var name: String = ""
    @State public var id = UUID()

    var body: some View {
        VStack {

            Button(action: {                
               self.presentationMode.wrappedValue.dismiss()
            }) {
                Text("Close")
            }

            Text("Add a new Category")
                .font(.largeTitle)

            TextField("Enter category name", text: $name)
                .padding(.all)
                .textFieldStyle(RoundedBorderTextFieldStyle())


            Button(action: {
                let category = Category(context: self.context)
                category.name = self.name
                category.id = self.id
                do {
                    try self.context.save()
                } catch {
                    self.name = "There is an error!"
                }

            }) {
                Text("SAVE \(self.name)")
            }

        }
    }
}

struct AddCategoryView_Previews: PreviewProvider {
    static var previews: some View {
        AddCategoryView()
    }
}

在这一行中,

Text("SAVE \(self.name)")

我正在打印(用于调试)变量名的值,我可以看到变量更改为 catch 语句中的值

 self.name = "There is an error!"

所以我知道保存失败了。但我不知道为什么。

在列表视图中,我有一个可以打开此模式的按钮;我从

更改了此 Button 的值
self.showAddModal.toggle()

let category = Category(context: self.context)
                category.name = "New Category"
                do {
                    try self.context.save()
                } catch {
                    self.name = "There is an error!"
                }

而且它有效!我可以看到列表视图已更新为该值。 这是列表视图的代码

struct CategoriesView: View {
    @Environment(\.managedObjectContext) var context
    @FetchRequest(entity: Category.entity(), sortDescriptors: []) var categories: FetchedResults<Category>
    @State private var showAddModal = false;
    @State public var name = ""
    var body: some View {
        VStack {
            Text("\(name)")
            List {
                ForEach(categories, id: \.id) { category in
                    VStack {
                        Text(category.name ?? "Unknown")
                    }
                }
            }

            Button(action: {
                let category = Category(context: self.context)
                category.name = "New Category"
                do {
                    try self.context.save()
                } catch {
                    self.name = "There is an error!"
                }

            }) {
                Text("+")
                    .font(.system(.largeTitle))
                    .fontWeight(.bold)
                    .foregroundColor(Color.white)
                    .multilineTextAlignment(.center)
                    .frame(width: 48, height: 48)
                    .background(Color.purple)
                    .cornerRadius(24)
                    .padding(.all)
                    .shadow(color: Color.black.opacity(0.3),
                            radius: 3,
                            x: 3,
                            y: 3)
            }.sheet(isPresented: $showAddModal) {
                AddCategoryView()
            }
        }
    }
}
struct CategoriesView_Previews: PreviewProvider {
    static var previews: some View {
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        return CategoriesView().environment(\.managedObjectContext, context)
    }
}

在过去的 2 个小时里,我一直在寻找和搜索解决方案,但我无法找出我的代码有什么问题。我也在模拟器上试过,但得到了同样的错误;我无法从 TextField 中保存核心数据。

提前致谢!

【问题讨论】:

    标签: swift core-data swiftui


    【解决方案1】:

    好的,我终于找到了解决方案,这可能不是正确的,但至少它有效。

    .sheet(isPresented: $showAddModal) {
                    AddCategoryView().environment(\.managedObjectContext, self.managedObjectContext)
                }
    

    是的,只需将带有上下文的环境传递给模态视图即可解决问题。我不确定这是不是正确的方法。

    【讨论】:

    • 这是正确的做法,否则您将在模态视图中获得新的上下文,而不是指向主视图的指针。
    猜你喜欢
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    • 2017-10-14
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    相关资源
    最近更新 更多