Search code examples
iosswiftcore-dataswiftui

Picker data not updating when sheet is dismissed


I am using coredata to save information. This information populates a picker, but at the moment there is no information so the picker is empty. The array is set using FetchedRequest.

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

This is how the picker is setup.

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

There is also a button that displays another sheet and allows the user to add a source.

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

If the user presses Add Source, the sheet is displayed with a textfield and a button to add the source. There is also a button to dismiss the sheet.

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.")
        })
    }
}

}

Once the sheet is dismissed, it goes back to the first view. The picker in the first view is not updated with the newly added source. You have to close it and reopen. How can I update the picker once the source is added by the user? Thanks!


Solution

  • The issue is with the ForEach signature you're using. It works only for constant data. If you want to use with changing data, you have to use something like:

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

    Note that hashValue will not be unique for two entity objects with the same name. This is just an example