My SwiftUI app has a segmented Picker and I want to be able to disable one or more options depending on availability of options retrieved from a network call. The View code looks something like:
@State private var profileMetricSelection: Int = 0
private var profileMetrics: [RVStreamMetric] = [.speed, .heartRate, .cadence, .power, .altitude]
@State private var metricDisabled = [true, true, true, true, true]
var body: some View {
VStack(alignment: .leading, spacing: 2.0) {
...(some views)...
Picker(selection: $profileMetricSelection, label: Text("")) {
ForEach(0 ..< profileMetrics.count) { index in
Text(self.profileMetrics[index].shortName).tag(index)
}
}.pickerStyle(SegmentedPickerStyle())
...(some more views)...
}
}
What I want to be able to do is modify the metricDisabled
array based on network data so the view redraws enabling the relevant segments. In UIKit this can be done by calls to setEnabled(_:forSegmentAt:)
on the UISegmentedControl but I can't find a way of doing this with the SwiftUI Picker
I know I can resort to wrapping a UISegmentedControl in a UIViewRepresentable but before that I just wanted to check I'm not missing something...
Since iOS 17 you can use the modifier selectionDisabled(_:)
:
VStack(alignment: .leading, spacing: 2.0) {
// ...(some views)...
Picker("", selection: $profileMetricSelection) {
ForEach(Array(profileMetrics.enumerated()), id: \.offset) { index, metric in
Text(metric.shortName)
.selectionDisabled(metricDisabled[index]) // 👈 here
.tag(index)
}
}
.pickerStyle(.segmented)
// ...(some more views)...
}