Я создаю очень простое приложение SwiftUI, следуя инструкциям. Я создал View, который содержит список элементов, @fetched из CoreData, и этот список отображается без проблем. Затем я добавил модальное окно с TextField
и Button
для сохранения данных. Это модальный код:
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!"
Так что я знаю, что сохранение не удается. Но я понятия не имею, почему.
В представлении списка у меня есть кнопка, которая откроет этот модал; Я изменил значение этой кнопки с
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.
Заранее спасибо!