【SwiftUI】Pickerの使い方

(2023/10/08 更新)

Pickerは複数の選択肢の中から1つの値をユーザーに選択させるUI部品です。

スポンサーリンク

環境

この記事で紹介する内容は、以下のバージョンでの動作を確認しています。

【Xcode】15.0
【iOS】17.0
【macOS】Ventura 13.6
スポンサーリンク

基本的な使い方

タイトル
Picker部品のタイトルを文字列で指定します。Pickerが配置されたコンテナや指定した表示スタイルによって、タイトルが表示されない場合もあります。

selection
選択値と連携するプロパティへの参照(Binding)指定します。
選択肢Viewで設定される選択値と型を一致させる必要があります。

選択肢View
選択項目の一覧を設定するViewです。
各選択項目は、独立したViewとして構成します。選択時にselectionと連携する選択値は、tag()修飾子で指定します。
選択値は一覧内でユニークでなければいけません。

使用例

以下は、5種類のフルーツから1つを選択するPickerのサンプルコードです。

選択値と連携するプロパティ(selectionValue)の初期値が、初期選択値として使用されます。
Pickerの選択が変更されると、selectionValueが更新され、画面上の選択値が再描画されます。
UntitledImage

スポンサーリンク

タイトルをカスタムViewにする

タイトルを文字列以外のカスタムViewで表したい場合は、次のイニシャライザを使用します。

使用例

UntitledImage

スポンサーリンク

選択肢を繰り返し処理(ForEach)で設定する

ForEachを使った繰り返し処理で選択肢のリストを設定できます。
これにより配列等のデータコレクションを選択肢リストとして設定可能です。
特筆すべき点として、ForEachを利用する際、.tag()による値の設定は不要となります。

ForEachには、【範囲指定】と【データ指定】の2種類の繰り返しがあります。
詳しくは、こちらの記事で解説しています。

【SwiftUI】ForEachの使い方(1/2)
(2023/09/18 更新) ForEachは繰り返し処理の中で、Viewを生成する仕組みです。文字列の入った配列をループしてそれぞれをTextViewに変換する、またはメニュー項目に追加するような動きを実現します。さらに、ForEach...

範囲指定による繰り返し

ForEachの【範囲指定】による繰り返しで、選択肢を設定するサンプルコードです。

配列(fruits)の各要素が、ForEachの繰り返し処理で、選択肢として設定されます。
0から始まるインデックスが自動的にselectionと連携するので、.tag()による値の設定は不要です。
ただし、selectionValueの初期値として設定した3は、実際には4番目の“バナナ”を示す点に注意してください。

UntitledImage

データ指定による繰り返し

ForEachの【データ指定】による繰り返しで、選択肢を設定するサンプルコードです。

この方式では、idに指定した値がselectionと連携します。
この例ではidに配列fruitsの各要素を指定していますので、連携するselectionValueもfruitsと同じ型(String)にします。

なお、idに指定される値は原則ユニークであるのが前提となります。
同一の要素が配列内に存在する場合、想定外の動きになりますので注意してください。

UntitledImage

勘違いしやすいselection連携の落とし穴

以下の例は、小学校の学年を選択するシチュエーションです。

選択肢には1から6までの学年が表示され、初期値は3年生を設定しているつもりですが、想定通りに動きません。
初期値として4年生が選択されてしまいますし、1年生を選択すると、選択値には想定外の0が代入されます。
これは、【範囲指定】の繰り返しの場合、selectionは必ず0から始まるインデックスと連携するためです。

次にように【データ指定】に変えて、ForEachのループアイテム値そのものと連携させると、想定した動きになります。

スポンサーリンク

表示スタイルの指定

Pickerは次のモディファイアで表示スタイルを任意に指定できます。

ただし、プラットフォームや配置されるコンテナの種類によっては、指定したスタイルが適用されない場合がある点に注意が必要です。

.menu

ボタンを押した時に、選択肢をメニューとして開くスタイルです。
一般的なガイドラインとして、選択肢が5つ以上ある場合は.menuを、5つ以下の場合は.inlineまたは.segmentedの使用がおすすめです。

UntitledImage

.inline

現在のコンテナ内に選択肢がインラインで表示されるスタイルです。
FormまたはList以外で使用した場合は.wheelスタイルが採用されます。

UntitledImage

.segmented

選択肢が横並びで表示されるスタイルです。
狭いスペースに複数の選択肢をコンパクトに表示するため、選択肢の数が多くなると表示が厳しくなります。一般的に、選択肢が2〜5程度の場合に使用します。
また選択肢には、シンプルなテキストラベルのみの指定が想定されており、HStackや他のViewを指定してもうまく動きません。

UntitledImage

.wheel

スクロール可能なホイール型のスタイルです
すべての選択肢が常に表示されるわけではないので、アルファベット順など、予測可能な順序に選択肢を並べるのを推奨します。

UntitledImage

.navigationLink

選択肢を別画面で表示するスタイルです。
NavigationStack管理下でのみ機能します。

UntitledImage

.automatic

スタイルが明示的に指定されない場合のデフォルト値です。
プラットフォームやコンテナの種類によって自動的にスタイルが選択されます。

スポンサーリンク

あわせて読みたい記事

【SwiftUI】DatePickerの使い方
DatePickerは日付と時間を選択するための専用Viewです。