Home > Blockchain >  iOS 15 SwiftUI 3 Picker binding is not working after changing @State value
iOS 15 SwiftUI 3 Picker binding is not working after changing @State value

Time:10-06

I'm trying to use Picker from SwiftUI, I had this code working for iOS 14 but when I updated the project to work with iOS 15 only now it's broken and Picker is not updating anymore after assigning @State on view appear.

I have created a new project from zero to test it and yes I could replicate the error.

here is the code I'm using:

import SwiftUI

struct Category: Identifiable {
    let id: UUID = UUID()
    let name: String
}

let categories: [Category] = [
    Category(name: "Cat 1"),
    Category(name: "Cat 2"),
    Category(name: "Cat 3")
]

struct ContentView: View {
    
    @State private var selectedCategory = -1
    
    var body: some View {
        NavigationView {
            Form {
                Section {
                    Picker("Category", selection: $selectedCategory) {
                        ForEach(0..<categories.count) {
                            Text(categories[$0].name)
                                .tag($0)
                        }
                    }
                }
            }
            .onAppear {
                self.selectedCategory = 1
            }
        }
    }
}

as you see in onAppear block, I'm changing selectedCategory value, this peace of code works well in iOS 14 but not iOS 15.

thanks

CodePudding user response:

Remove self.selectedCategory = 1 from onAppear and it will work fine.

struct ContentView: View {

    @State private var selectedCategory = 1

        var body: some View {
            NavigationView {
                Form {
                    Section {
                        Picker("Category", selection: $selectedCategory) {
                            ForEach(0..<categories.count) {
                                Text(categories[$0].name)
                                    .tag($0)
                            }
                        }
                    }
                }
                .onAppear {
//                    self.selectedCategory = 1
                }
        
            }
        }
}

you can set default value directly while declaring

@State private var selectedCategory = 1 //this will set your default value

CodePudding user response:

Seems like iOS 15 does not work like before to change the value of State var and send it as Binding to a Picker.

the issue is that the State var selectedCategory is sent to the Picker as Binding and when I try to change the value of selectedCategory var on appearing the view, the binding is not being updated and the Picker value does not change when you select a different category.

What I did is to change the selectedCategory value in the init function before initializing the Picker:

import SwiftUI

struct Category: Identifiable {
    let id: UUID = UUID()
    let name: String
}

let categories: [Category] = [
    Category(name: "Cat 1"),
    Category(name: "Cat 2"),
    Category(name: "Cat 3")
]

struct ContentView: View {
    
    @State private var selectedCategory = -1
    
    init() {
        self._selectedCategory = State(initialValue: 1)
    }
    
    var body: some View {
        NavigationView {
            Form {
                Section {
                    Picker("Category", selection: $selectedCategory) {
                        ForEach(0..<categories.count) {
                            Text(categories[$0].name)
                                .tag($0)
                        }
                    }
                }
            }
        }
    }
}

Why do I need to assign a value on the init? this is because in my project I need to update a Core Data record and I send the record to the view as ObservedObject and to change the category I need to change selectedCategory to have the value of the Core Data record and not the default value, by changing the value in onAppear the Picker get broken and does not work anymore, so the best way to do this in iOS 15 is to set the value in the init function and not in onAppear.

  • Related