⚒️

[SwiftUI] enumから生成したPickerで未選択の状態を作る / バインドした値が変化しない場合の対処法

2021/03/18に公開

以下のようなCaseIterableなenumがあったとして、PickerでForEachで生成する3つの選択肢に加えて、未選択の状態を選べるようにします。

enum AxisColor: String, CaseIterable {
	case red = "赤軸"
	case blue = "青軸"
	case brown = "茶軸"
}

Pickerを配置するViewは以下のようになります。選択した AxisColor を代入するプロパティをオプショナルにし、nilの時を未選択状態にします。そうした時、未選択状態のPickerのtagの中身を Text("選択しない").tag(nil) のようにnilにすると Generic parameter 'V' could not be inferred というエラーがでます。

この時tagの中身は、AxisColor?.none と書くことでこのエラーを回避できます。

また特にXcodeではエラーが出ないのですが、Text(color.rawValue).tag(color) のようにした場合、selectionにバインドした値が変化しなくなるので、 tagの中身は AxisColor?.some(color) と書きます。

struct SelectAxisColorView: View {
...
@Binding private var selectedAxisColor: AxisColor? //オプショナルにして、nilを未選択状態とします

var body: some View {
	Picker("軸の色", selection: $selectedAxisColor) {
		Text("選択しない").tag(AxisColor?.none)
		ForEach(AxisColor.allCases, id: \.self) { color in
			Text(color.rawValue).tag(AxisColor?.some(color)
		}
	}
}

Discussion