[SwiftUI] Picker での要素選択により設定される値

SwiftUI

Picker でのユーザーによる選択がどのように値として扱われるかを説明します。

Picker の使い方

Picker は、ユーザーが提示された選択肢から選択することができるコントロールです。

Picker 動作例

「Picker 動作例」

Picker コード

//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2020/10/29
//  © 2020  SmallDeskSoftware
//

import SwiftUI

enum Options: String, Identifiable, CaseIterable {
  case option1 = "OptionValue1"
  case option2 = "OptionValue2"
  case option3 = "OptionValue3"
  var id: String { self.rawValue }
}

struct ContentView: View {
  @State private var selectedOption: Options = .option1
  var body: some View {
    VStack {
      Picker("Select option", selection: $selectedOption, content: {
        Text("Option1").tag(Options.option1)
        Text("Option2").tag(Options.option2)
        Text("Option3").tag(Options.option3)
      })
      .padding()

      Text("selected option value is \(selectedOption.rawValue)")
        .padding()
    }
    .padding()
  }
}

selection に設定される値

選択肢が選択されると、selection に渡された Binding に選択肢の値が セットされます。

このため、選択肢の各要素に設定される .tag の値のタイプは、Picker の selection に渡される値のタイプと 一致する必要があります。

つまり、選択肢の .tag に設定された値が、selection に設定されることになります。

ForEach による自動設定

選択対象が、Identifiable の時に、ForEach を使用すると、自動的に .tag に rawValue が設定されると Apple のドキュメントに記載されています。

ですが、Xcode12.1 時点では、期待通りに動作しません。

ForEach を使った Picker

//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2020/10/29
//  © 2020  SmallDeskSoftware
//

import SwiftUI

enum Options: String, Identifiable, CaseIterable {
  case option1 = "OptionValue1"
  case option2 = "OptionValue2"
  case option3 = "OptionValue3"
  var id: String { self.rawValue }
}

struct ContentView: View {
  @State private var selectedOption: Options = .option1
  @State private var selectedFlavor = Flavor.chocolate
  
  var body: some View {
    VStack {
      Picker("Select option", selection: $selectedOption) {
        ForEach(Options.allCases, id:\.id) { option in
          Text(option.rawValue.capitalized)
            .tag(option)   // (1)
        }
      }
      .padding()

      Text("selected option value is \(selectedOption.rawValue)")
        .padding()
    }
    .padding()
  }
}
コード解説
  1. Apple のドキュメントでは、この .tag は不要のはずですが、Xcode12.1 では、この指定が無いと 値が選択されません

まとめ: Picker で選択された値の扱い

Picker で選択された値の扱い
  • content に渡された要素が選択肢として表示される
  • 選択肢が選択されると、その選択肢の .tag 値が selection に設定される
  • 選択肢に、.tag 指定された値のタイプと selection のタイプは一致する必要がある

説明は以上です。
不明な点やおかしな点ありましたら、ご連絡いただけるとありがたいです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です