Stanislav Poslavsky
Stanislav Poslavsky

Reputation: 2428

SwiftUI: ForEach in Picker doesn't update

I have an array of elements, from which I want to chose one using Picker, and I have a Button which simply adds a new element to the array. The thing is, when I add an element, the Picker choices are not updated. It doesn't work with DefaultPickerStyle, but works with SegmentedPickerStyle.

The code:

import SwiftUI

struct ExampleView: View {
    @State
    var array : Array<Int> = [Int]()
    @State
    var selection : Int = 0

    var body: some View {
        VStack {
            Picker("", selection: self.$selection) {
                ForEach(self.array, id : \.self) { i in
                    Text(String(i))
                }
            }
            // uncomment, and picker will refresh upon pushing the button
            //.pickerStyle(SegmentedPickerStyle())

            Button(action: {
                self.array.append(self.array.count)
            }){
                Text("Add me: " + String(self.array.count))
            }
        }
    }
}

struct ExampleView_Previews: PreviewProvider {
    static var previews: some View {
        ExampleView()
    }
}

Is there any way to fix this? I really need to update the Picker (in its default styling). Xcode Version 11.2.1 (11B500).

Upvotes: 2

Views: 3262

Answers (1)

Stanislav Poslavsky
Stanislav Poslavsky

Reputation: 2428

As @e-coms pointed out, there is a similar question. An acceptable workaround found by @p-ent (github) is to re-assign a unique .id(...) for Picker on each button push, to force its update. Adapted to my question:

UPD: even better, thanks @e-coms

import SwiftUI

struct ExampleView: View {
    @State
    var array : Array<Int> = [0,1,2]
    @State
    var selection : Int = 0

    var body: some View {
        VStack {
            Picker("", selection: self.$selection) {
                ForEach(self.array, id : \.self) { i in
                    Text(String(i))
                }
            }
            .id(self.array)

            Button(action: {
                self.array.append(self.array.count)
            }){
                Text("Add me: " + String(self.array.count))
            }
        }
    }
}

struct ExampleView_Previews: PreviewProvider {
    static var previews: some View {
        ExampleView()
    }
}

Upvotes: 4

Related Questions