This is a demonstration of a problem that manifests itself in Swift UI Picker
view if you attempt to update the data source. Consider:
Picker(selection: $viewModel.segmentedPickerValue, label: Text("")) {
ForEach(viewModel.objects) { object in
Text(object.string)
}
}
.pickerStyle(SegmentedPickerStyle())
That works fine. As does:
List {
ForEach(viewModel.objects) { object in
Text(object.string)
}
}
But this does not:
Picker(selection: $viewModel.wheelPickerValue, label: Text("")) {
ForEach(viewModel.objects) { object in
Text(object.string)
}
}
.pickerStyle(WheelPickerStyle())
It would appear that the Picker
is not correctly re-retrieving the data source generated by the ForEach
as it does in SegmentedPickerStyle
or in the List
.
The salient code is found in the ContentView
. This is just a view whose @ObservedObject
is updated every three seconds. The UIPickerView
-based control does't update, but the List
and the UISegmentedControl
-based control are. The fact that this is updating every three seconds is not critical ... anything that updates the content
of the UIPickerView
wrapped by Picker
after the initial presentation won't get rendered correctly.
The common solution is to have the View
remove the picker and then re-add it (e.g. with some secondary @Published
property indicating whether it is loading or not), but that's kludgy and is just a work-around this bug.
Iโm running Xcode 11.4.1 (11E503a) on Catalina 10.15.4 (19E266) on MacBook Pro (15-inch, 2018). The behavior manifests in both devices and simulators, but in iOS 13 only.
In Xcode 12.0 beta 1 (12A6159), on iOS 14 beta 1, this appears to have been fixed.
April 20, 2020
Copyright (c) 2020 Rob Ryan. All Rights Reserved.
See License.