8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SwiftUIでForEachを使ったPickerの使い方

Posted at

住所入力欄を作っているときに、都道府県をPickerで選択式にすることにしました。

しかし、完成までけっこうつまってしまったので備忘録として残しておきます。

##当初書いてみた間違ったやり方

@State private var selectedPrefecture = 0
Form {
    // Pickerを使う
    Picker(selection: $selectedPrefecture,
            // ラベル部分
            label: HStack {
            Text("都道府県")
            Spacer()
            Text(JapanesePrefecture(rawValue: selectedPrefecture)!.nameWithSuffix)
        }
    ) {
        // 選択部分
        ForEach(JapanesePrefecture.allCases, id: \.self) {
            Text($0.nameWithSuffix)
        }
    }
}

今回は都道府県の選択用Pickerなので、都道府県を定義した JapanesePrefecture を使っています。
選択した都道府県が分かるようにラベル部分にもTextを追加しています。

しかし、これでは期待通りの動作にはなりません。
いくらPickerで選択してもその選択が反映されないからです。

##期待通りの挙動になった書き方
Picker部分を以下のように書き換えたところ、期待通りの見た目・挙動になりました!

Picker(selection: $selectedPrefecture,
       label: Text("都道府県")
) {
    ForEach(0..<JapanesePrefecture.allCases.count, id: \.self) { index in
        Text(JapanesePrefecture(rawValue: index)!.nameWithSuffix).tag(index)
    }
}

ForEachを個数で繰り返すように書き、indexでtagを付与します。
選択した都道府県はTextを用意しなくても自動で表示されます。

###初期選択を空にしたい場合
このままでは、
@State private var selectedPrefecture = 0
と初期値を0に設定しているので「北海道」が選択された状態になっています。
初期選択を空にしたい場合は -1 など該当しない数値を指定することで空にすることができました。

##既知の問題点
都道府県の選択を行う画面では、「東京都」などのラベルをタッチして行いますが、デフォルトでは文字が左寄せになっており、セルの文字が書かれていない部分はタッチして選択することができません。
セルならどこでも選択可能にしたいのですが、ちょっと分からなかったので現段階ではそのままにしてあります。

もしご存知の方がいらっしゃいましたら教えて頂けると嬉しいです。

##参考
都道府県のenumを作成するときはこちらを参考にさせていただきました。
https://qiita.com/EnVacance/items/95dd6b77e962d4723a76

8
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?