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
.