【独学】はじめてのiOSプログラミング – 7.2 ピッカー表示

ピッカー表示

同じ種類のコンテンツを並べて表示するリストに対して、並べたコンテンツを選択するピッカーというUIもあります。ここではピッカーの表示について学びましょう。

ピッカーの利用

プロジェクトを生成後、UIのライブラリからPickerをプレビューの「Hello, world!」のテキストの上にドラッグ&ドロップします。

struct ContentView: View {
    var body: some View {
        VStack {
            Picker(selection: .constraint(1), label: Text("Picker")) {
                Text("1").tag(1)
                Text("2").tag(2)
            }
            Text("Hello, world!")
                .padding()
        }
    }
}

上記のコードが追加されます。コード内の tag メソッドは、UIに数値をタグづけするメソッドです。
https://developer.apple.com/documentation/swiftui/form/tag(_:)
タグからUIを取得する処理の前段階で利用されます。サンプルではタグは利用しないのでここでは気にしないでください。
ここでシミュレーターを起動してピッカーの動作を確認してみます。

「1」の部分をクリックすると、選択用のリストが表示されることを確認してください。

ピッカーの選択肢を外部から指定する

リストの時と同様に、外部からの変数を利用してピッカーを表示してみます。
リスト表示のサンプルと同様に Item構造体を利用して選択肢を配列で用意します。

struct Item: Identifiable {
    var id = UUID()
    var title: String
}

struct ContentView: View {
    let items = [Item(title: "いぬ"),
                 Item(title: "ねこ"),
                 Item(title: "うさぎ")]
    
    @State private var selection: Int = 0
    @State private var selectTitle: String = ""
    
    var body: some View {
        VStack {
            Picker(selection: $selection, label: Text("Picker")) {
                ForEach(0..<self.items.count) { index in
                    Text(self.items[index].title).tag(index)
                }
            }.onChange(of: selection) {
                self.selectTitle = self.items[$0].title
            }
            Text(self.selectTitle)
                .padding()
        }
    }
}

コード内の赤点線部分はリスト表示のサンプルと同じコードです。
Picker自体が配列をインスタンスの引数にする仕様ではないので、赤線部分で配列の要素を展開して選択肢を作成しています。
配列の各要素を取得しているForEach文の書式は次の通りです。

ForEach( 開始数 ..< 終了数 ) { 数 in 
  // 処理
}

ForEach文では数値を最初と最後を指定してループできます。ForEachの後の「( )」に開始数から終了数までを「..<」で記述します。「..<」では終了数を含まないところまでループします。
終了数を含む場合は「…」で記述します。サンプルでは0から配列itemsの要素数までをループしおり、サンプルコード内の変数 index に書式の「数」が格納されます。
ForEachの後のブロックで、開始数から終了数までを1つ単位で得られますので、それを配列の添字(インデックス)にして配列の要素を取得しています。
配列では次の処理が可能です。
・countプロパティで配列の要素数を取得できる
・最初の要素から0,1,2,…というインデックスで「配列の名前[インデックス]」で各要素を取得できる
このことを利用して、0から配列の要素数をループして各要素を取得しています。
サンプルを実行すると、配列itemsの選択肢でピッカーが表示できることが確認できます。

バインディング変数を利用して選択された項目を取得する

ピッカーは入力系UIなので、バインディング変数を利用するサンプルも作成してみます。
ピッカーの書式は次の通りです。

Picker(selection: Binding<Int>, label: Text) {
    // 選択肢の表示処理
}

selectionラベルで指定する引数がバインディング変数にあたります。Swiftでは、ピッカーで選択されたものは、インデックスのみを取得する仕様となっています。
選択肢の中からどれが選択されたかは、選択されたインデックスに相当する項目を取得する処理を作成しなければならないことを覚えておいてください。

サンプルでは、ピッカーのインデックスに利用するバインディング変数を「selection」、選択されたインデックスで参照できる項目を「selectTitle」で宣言しています。
最初に、Pickerのインスタンスの引数にselectionを指定し、値が変わった際に実行されるonChangeメソッドで、selectTitleの値を変更する処理を作成します。
この辺りの処理は、6.2 データバインディング のサンプルと同様です。
次に、selectTitleの値を画面で表示できるようにTextの「Hello, world!」の部分を置き換えています。
ピッカーは初期状態では、変数 selection の値が0なので「いぬ」が選択されており、画面のTextも「いぬ」の表示です。ピッカーの選択時に、変数 selection の値が選択されたピッカーのインデックスに変わります。それに伴って、onChangeメソッドも実行され、変数 selectTitle の値もピッカーのインデックスに応じた値に変更され、画面にTextの表示も変数 selectTitle の値になります。
サンプルを実行すると、選択した項目を画面に表示できます。

ピッカーで「ねこ」を選択すると、画面のTextの表示も「ねこ」に変更されることがわかります。
ピッカーの例では、UIの表示だけでなく、構造体の利用、配列の処理、データバインデングなど複数の技術を学ぶことができます。
Swiftの学習を進めるにあたっては、ドキュメントのサンプルを参照するなどして1つの画面を作る際にも複数の処理を学べるように工夫するといいです。

タイトルとURLをコピーしました