[iOS UIKit] UIPickerView入門
はじめに
この記事ではiOSアプリ開発におけるUIPickerViewに好きなデータを表示する方法について紹介します。
後編もあるので良ければそちらもご覧ください↓
https://zenn.dev/fummicc1/articles/e3ed945c6d4dfc
完成

全体の流れ
手順
StoryboardにUI部品を配置
最初にMain.storyboardから以下のように画面レイアウトを構築します。
| 使用したUIパーツ | 個数 |
|---|---|
UIPickerView |
2つ |
UILabel |
2つ |

ViewController.swift
UIパーツの宣言
次に、ViewController.swiftにプログラムを書いていきます。
最初に先ほど作成したUIパーツを@IBOutlet varを用いて変数として宣言しておきます。
// ViewControllerクラスの中に記述
@IBOutlet var foodPickerView: UIPickerView! // 食べ物のPickerView
@IBOutlet var drinkPickerView: UIPickerView! // 飲み物のPickerView
UIPickerViewDataSourceとUIPickerViewDelegateの設定
UIPickerViewDataSourceを利用することで、PickerViewに表示されるデータを設定することができます。
UIPickerViewDelegateも後ほど利用します。UIPickerViewDelegateはPickerの見た目を変更したり、Pickerを選択した際の処理を記述する際に必要になります。
// viewDidLoadメソッドの中に記述
override func viewDidLoad() {
super.viewDidLoad()
// データソースの設定
drinkPickerView.dataSource = self
foodPickerView.dataSource = self
// デリゲートの設定
drinkPickerView.delegate = self
foodPickerView.delegate = self
}
また、デリゲート/データソースにselfを代入する場合、以下のようなエラーが発生するはずです。

これは、ViewControllerがUIPickerViewDelegateとUIPickerViewDataSourceに準拠していないために発生するので、以下のようにViewControllerの頭を変更します。
また、AというクラスがBというデリゲートに準拠するには以下のように記述します。
class A: B {
}
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
上に沿ってUIPickerViewDataSourceとUIPickerViewDelegateを追記するとエラーが解消されます。
PickerViewに表示するデータの変数を宣言
次に、PickerViewに表示するデータを保存した変数を宣言します。
foodPickerViewに表示するデータはfoodArrayに保存し、drinkPickerViewに表示するデータはdrinkArrayに保存しています。
// 飲み物のデータの配列
var drinkArray: [String] = [
"爽健美茶",
"麦茶",
"コーラ",
"オレンジジュース",
"天然水"
]
// 食べ物のデータの配列
var foodArray: [String] = [
"ラーメン",
"トマト",
"生ハム",
"きゅうり",
"納豆",
"お米"
]
データソースを実装
UIPickerViewDataSourceで定義されているメソッドは必ず実装する必要があり、2つのメソッドを実装していきます。
1. PickerViewの列の数を決めるメソッド
以下のメソッドになります。
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
今回のアプリでは列は1つの想定なのでreturn 1としておきます。
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return 1
}
2. PickerViewの列一つに対する行の数を決めるメソッド
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
今回はfoodPickerViewに対してはfoodArray.countだけ、drinkPickerViewに対してはdrinkArray.countの数だけを表示したいので以下のように書き換えます。
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == foodPickerView {
return foodArray.count
}
if pickerView == drinkPickerView {
return drinkArray.count
}
return 0
}
ここまでで実行をすると下のように、表示したい要素の数は一致しているのですが、中身に?と表示されてしまいます。

デリゲートの実装
?がピッカーに表示されてしまう現象はPickerViewに表示する文字列を設定していないために起こります。
UIPickerViewDelegateに準拠していれば、以下のメソッドが使用でき、ピッカーに表示されるタイトルを設定することができます。
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
rowという引数には行数が格納されているので、foodArray[row]もしくはdrinkArray[row]として順にデータを設定していきます。ピッカーの行数を設定したときと同じく、pickerViewという引数がfoodPickerViewなのかdrinkPickerViewなのかで表示する文字列が変わってくるのでif文を用いて条件分岐しています。
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == foodPickerView {
return foodArray[row]
}
if pickerView == drinkPickerView {
return drinkArray[row]
}
return nil
}
完成(再掲)

コード全貌
GitHubにアップロードしました!
Discussion