SwiftUI 从 CoreData 设置初始选择器值

Posted

技术标签:

【中文标题】SwiftUI 从 CoreData 设置初始选择器值【英文标题】:SwiftUI Setting Initial Picker Value From 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 ?? ""
                                
                        
                    
                
...

【问题讨论】:

【参考方案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'。

以上是关于SwiftUI 从 CoreData 设置初始选择器值的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI Picker 从 CoreData 返回空字符串

从 coredata SwiftUI 中删除多行

在 SwiftUI 中更新 CoreData 时更新状态变量

SwiftUI 如何使 CoreData 列表在 macOS 上可选择和可双击

SwiftUI - 没有初始值的状态

SwiftUI CoreData 选择器问题