Search code examples
swiftswiftuiios13ios14

How can I use Core Data value from picker? #SwiftUI #CoreData


struct PickerView: View {

var items0 : [PageName]
@State var selectedPage: PageName?

init(items0: [PageName]) {
    self.items0 = items0
    self._selectedPage = State(initialValue: items0.first)
}

var body: some View {
    Picker(selection: $selectedPage, label: Text("Page")) {
        ForEach(items0) { item in
            Text(item.pageName ?? "").tag(item as PageName?)
        }
    }
    Text("\((selectedPage?.pageName)!)")
}







NavigationView {
                Form {
                    PickerView(items0: Array(items0))
                }
                .foregroundColor(.blue)
                .background(Color.yellow)
            }

I can successfully pick the value of Core Data in Picker, but I don't know how can I use this value in my main View...

Some much things I already tried, but that Core Data drives me just crazy.

Can someone help me that I can use the picked value of the picker with Core Data in SwiftUI?


Solution

  • I misunderstood your issue with my original comment see below. There is a lot of info in the comments.

    import SwiftUI
    struct ParentPickerView: View {
        @Environment(\.managedObjectContext) private var viewContext
        @FetchRequest(
            sortDescriptors: [NSSortDescriptor(keyPath: \PageName.pageName, ascending: true)],
            animation: .default)
        private var items0: FetchedResults<PageName>
        //State is a source of truth
        @State var selectedPage: PageName? = nil
        var body: some View {
            NavigationView {
                Form {
                    Text(selectedPage?.pageName ?? "not selected")
                    PickerView(items0: Array(items0), selectedPage: $selectedPage)
                }
                .foregroundColor(.blue)
                .background(Color.yellow)
            }
        }
    }
    struct PickerView: View {
        //If you don't need all your PageName in your parentView it would be best to have the fetch here
        //    @Environment(\.managedObjectContext) private var viewContext
        //    @FetchRequest(
        //        sortDescriptors: [NSSortDescriptor(keyPath: \PageName.pageName, ascending: true)],
        //        animation: .default)
        //    private var items0: FetchedResults<PageName>
        var items0: [PageName]
        //Binding is a two-way connection
        @Binding var selectedPage: PageName?
        //You don't need custom init in SwiftUI because they are struct
        //    init(items0: [PageName], selectedPage: Binding<PageName?>) {
        //        self.items0 = items0
        //        self._selectedPage = selectedPage
        //
        //        //@State Init here is bad practice as you are experiencing it becomes a dead end
        //        //self._selectedPage = State(initialValue: items0.first)
        //    }
        var body: some View {
            Picker(selection: $selectedPage, label: Text("Page")) {
                ForEach(items0) { item in
                    Text(item.pageName ?? "").tag(item as PageName?)
                }
            }
            Text("\((selectedPage?.pageName ?? "not selected"))")
                
                .onAppear(){
                    //Set your initial item here only if the selected item is nil
                    if selectedPage == nil{
                        selectedPage = items0.first
                    }
                }
        }
    }