【问题标题】:SwiftUI Setting Initial Picker Value From CoreDataSwiftUI 从 CoreData 设置初始选择器值
【发布时间】:2020-03-06 23:36:29
【问题描述】:

我正在努力弄清楚如何让我的选择器显示已经存储的 CoreData 值。我希望它显示在选择器的右侧,就好像用户刚刚选择了它一样。我曾尝试在选择器之前添加self.updatedItemAttribute = self.editItem.attribute ?? "" 以设置初始值,但这并没有建立。我也尝试在@State(例如@State var updatedItemAttribute: String = self.editItem.attribute)中定义它,但这也没有建立。如果我在选择器之前添加一个TextField,它将设置值,但我不希望有一个带有值的TextField,只是为了设置它。关于如何在选择器之前将updatedItemAttribute 设置为editItem.attribute 的任何想法?谢谢。

import CoreData
import SwiftUI

struct EditItemView: View {
    @Environment(\.managedObjectContext) var moc
    @Environment(\.presentationMode) var presentationMode
    @ObservedObject var editItem: Item

    @State var updatedItemName: String = ""
    @State var updatedItemAttribute: String = ""

    let attributes = ["Red", "Purple", "Yellow", "Gold"]

    var body: some View {
        NavigationView {
            Form {
                Section {
                    TextField("Name of item", text: $updatedItemName)
                        .onAppear {
                            self.updatedItemName = self.editItem.name ?? ""
                    }
                    Picker("Test attribute", selection: self.$updatedItemAttribute) {
                        ForEach(attributes, id: \.self) {
                            Text($0)
                                .onAppear {
                                    self.updatedItemAttribute = self.editItem.attribute ?? ""
                                }
                        }
                    }
                }
...

【问题讨论】:

    标签: ios core-data swiftui


    【解决方案1】:

    你必须在init中这样做,如下所示

    struct EditItemView: View {
        @Environment(\.managedObjectContext) var moc
        @Environment(\.presentationMode) var presentationMode
        @ObservedObject var editItem: Item
    
        @State private var updatedItemName: String
        @State private var updatedItemAttribute: String
    
        init(editItem item: Item) {             // << updated here
            self.editItem = item
            self._updatedItemName = State<String>(initialValue: item.name ?? "")
            self._updatedItemAttribute = State<String>(initialValue: item.attribute ?? "")
        }
    
        let attributes = ["Red", "Purple", "Yellow", "Gold"]
    
        var body: some View {
            NavigationView {
                Form {
                    Section {
                        TextField("Name of item", text: $updatedItemName)
                        Picker("Test attribute", selection: self.$updatedItemAttribute) {
                            ForEach(attributes, id: \.self) {
                                Text($0)
                            }
                        }
                    }
                }
            }
        }
    }
    

    【讨论】:

    • 那行得通。非常感谢。我需要了解的一件事是为什么我必须将我的预览返回从EditItemView(editItem: item) 更改为EditItemView(item),以及我从上一页到此页面的调用从EditItemView(editItem: self.myItem).environment(\.managedObjectContext, self.moc) 更改为EditItemView(self.myItem).environment(\.managedObjectContext, self.moc)。我不明白为什么使用init 消除了使用editItem 调用和返回的需要。你碰巧知道吗?
    • @Arkyyn,这是由于 init 的签名 - init(_ item: Item)。您可以将其更改为init(editItem: Item),并修复第一个成员分配,以获取您以前的语法。
    • 所以,我试过了,我仍然缺少一些东西。我试过`init(editItem:Item){self._updatedItemName = State(initialValue:editItem.name??“”)self._updatedItemAttribute = State(initialValue:editItem.attribute??“”)}`但我得到一个错误,上面写着“从初始化程序返回而不初始化所有存储的属性。上面对我来说更有意义,但我显然遗漏了一些东西。有什么想法吗?我有另一种工作方式。只是想理解。谢谢寻求帮助。
    • 哇。我永远不会得到我需要self.editItem = editItem。我还必须将item.nameitem.attribute 更改为editItem.nameeditItem.attribute'. What is the self.editItem = editItem` 做什么?似乎无关紧要,但显然不是。
    • @Arkyyn,再次更新 )),因为真正引入了命名错误,将 'argument label' 和 'argument' 和 'member' 明确分开以显示 'what is what'。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-11
    相关资源
    最近更新 更多