【问题标题】:Picker data not updating when sheet is dismissed关闭工作表时选择器数据不更新
【发布时间】:2025-12-27 18:35:06
【问题描述】:

我正在使用 coredata 来保存信息。此信息填充选择器,但目前没有信息,因此选择器为空。数组是使用 FetchedRequest 设置的。

@FetchRequest(sortDescriptors: [])
var sources: FetchedResults<Source>
@State private var selectedSource = 0

这就是选择器的设置方式。

Picker(selection: $selectedSource, label: Text("Source")) {
    ForEach(0 ..< sources.count) {
        Text(sources[$0].name!)
                            
    }
}

还有一个按钮可以显示另一个工作表并允许用户添加源。

Button(action: { addSource.toggle() }, label: {
    Text("Add Source")
})
    .sheet(isPresented: $addSource, content: {
        AddSource(showSheet: $addSource)
})

如果用户按下添加源,工作表将显示一个文本字段和一个用于添加源的按钮。还有一个关闭工作表的按钮。

struct AddSource: View {
@Environment(\.managedObjectContext) var viewContext
@Binding var showSheet: Bool
@State var name = ""

var body: some View {
    NavigationView {
        Form {
            Section(header: Text("Source")) {
                TextField("Source Name", text: $name)
                Button("Add Source") {
                    let source = Source(context: viewContext)
                    source.name = name
                    
                    do {
                        try viewContext.save()
                        
                        name = ""
                    } catch {
                        let error = error as NSError
                        fatalError("Unable to save context: \(error)")
                    }
                }
            }
            
        }
        .navigationBarTitle("Add Source")
        .navigationBarItems(trailing: Button(action:{
            self.showSheet = false
        }) {
            Text("Done").bold()
                .accessibilityLabel("Add your source.")
        })
    }
}

}

一旦关闭工作表,它就会返回到第一个视图。第一个视图中的选取器不会使用新添加的源进行更新。您必须将其关闭并重新打开。用户添加源后如何更新选择器?谢谢!

【问题讨论】:

    标签: ios swift core-data swiftui


    【解决方案1】:

    问题在于您使用的 ForEach 签名。它仅适用于常量数据。如果您想使用更改数据,则必须使用以下内容:

    ForEach(sources, id: \Source.name.hashValue) {
        Text(verbatim: $0.name!)
    }
    

    请注意,对于两个同名的实体对象,hashValue 不会是唯一的。这只是一个例子

    【讨论】:

    • 谢谢!现在几乎可以完美运行。当我添加一个源并返回时,新的源就在那里。奇怪的是新的来源被添加到选择器的中间,而不是最后。如果我重新加载,源的顺序是正确的。你知道是什么原因造成的吗?
    • 如果要按照创建日期的顺序排序,需要给你的数据模型添加时间戳保存,并且需要在你的@FetchRequest中添加排序描述符,按照日期。否则,您可以通过传递排序描述符来按名称对其进行排序