In the attached minimal reproducing app, the picker in the List works as expected while the one in the sheet resets every time the List view updates (this demo app displays a random byte value that is updated every second).
Can anyone explain why this happens and how to solve the issue, i.e. how can I have a picker in a sheet on a view without the picker getting reset when the parent view receives updates?
Somebody asked the same question here, but it is unanswered, it has different example code: https://www.hackingwithswift.com/forums/swiftui/picker-value-resets-when-in-a-sheet-but-works-fine-in-parent-view/17211
import SwiftUI
@main
struct SwiftUITestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
// MARK: - ContentView
struct ContentView: View {
@State var selectedValue: Int = 0
@State var isSheetPresented: Bool = false
@State var randomByte: UInt8 = 0
var body: some View {
List {
Text("Frequently updated random byte: \(randomByte)")
Text("Note how the picker works as expected here:")
MyPicker()
Text("But not within a sheet:")
Button("Select a value inside a sheet") {
isSheetPresented = true
}
}
.sheet(
isPresented: $isSheetPresented,
onDismiss: {
isSheetPresented = false
},
content: {
List {
VStack(alignment: .leading, spacing: 16) {
Text("Select a value close to the bottom of the drop down menu.")
Text("Then open the drop down menu again.")
Text("Note that the drop down menu scrolls each time `randomByte` changes.")
}
MyPicker()
}
}
)
.task {
while true {
try! await Task.sleep(nanoseconds: 1_000_000_000)
randomByte = UInt8.random(in: .min ... .max)
}
}
}
}
// MARK: MyPicker
struct MyPicker: View {
@State var selectedValue: Int = 0
var body: some View {
Picker("Value", selection: $selectedValue) {
ForEach(0..<100, id: \.self) { value in
Text("\(value)").tag(value)
}
}
.onChange(of: selectedValue) { _ in
print("•••• selectedValue", selectedValue)
}
}
}
// MARK: Preview
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}