[iOS UIKit] UIPickerView×CustomViewを入門する
はじめに
この記事ではUIPickerView
に表示する内容をUINib
を用いて作成します。また、UINib
を用いて独自にデザインしたビューをこの記事ではCustomView
を呼ぶことにします。
また、前の記事の続きになっているので良ければそちらもご確認ください。→https://zenn.dev/fummicc1/articles/d14dfba7e228e3
完成
下の画像のように枠線と影をつけることで要素ごとの区切りが明確なPickerViewを作成していきます。
全体の流れ
手順
CustomViewの作成(Xibファイル)
最初にUIPickerView
に表示するビューのファイルを作成します。
MacのメニューバーからFile
→New
→File
と選択をし、以下の画面からView
を選びます。
画面右のNext
を選択すると、ファイルの名前を入力する画面に移動します。実際は好きな名前で構いませんが、説明上CustomPickerContent
という名前で作成した程で話を進めます。
CustomViewの作成(Swiftファイル)
次に作成したXibファイルに対してSwiftファイルも作成します。
Xibファイルの作成と同様にMacのメニューバーからFile
→New
→File
と順に選択肢、以下の画像にあるようにCocoa Touch Class
を選択します。
Xibファイルで行ったように画面右下のNext
を選択すると、ファイルの名前を入力する欄が出てきますが、Xibファイルの名前を揃えて、CustomPickerContent
という名前で作成しておきます。また、Subclass of
がUIView
に設定されていること、Language
がSwift
に設定されていることを確認してください。
CustomViewのレイアウト作成
次に、作成したXibファイル(CustomPickerContent.xib
)を編集していきます。
今回は枠線と影をつけたいのですが、それらの実装はSwiftファイルで行うのでXibファイルにはUILabel
を一つだけ配置しておきます。
CustomViewの実装
次にCustomPickerContent.swift
を変更して、ラベルの関連付けや、影・枠線の実装を行います。
コメントを振ってありますが、具体的なコードの説明に関しては本題からずれてしまうので割愛します。
import UIKit
class CustomPickerContent: UIView {
// Xib上に配置したUILabel
@IBOutlet var label: UILabel!
// Xibが読み込まれると実行される
override func awakeFromNib() {
super.awakeFromNib()
// 影をつけている
// 影のずれを設定
layer.shadowOffset = CGSize(width: 0, height: 2)
// 影の不透明度を設定(0~1の範囲で大きいほど影が濃い)
layer.shadowOpacity = 0.4
// 影の色を設定
layer.shadowColor = UIColor.gray.cgColor
// 枠線をつけている
layer.borderWidth = 2
}
}
CustomViewのSwiftファイルとXibファイルを紐付ける
次に、CustomPickerContent.swift
とCustomPickerContent.xib
を紐づけていきます。
最初にXibファイルを開いて、以下のようにCustomViewのCustom Class
という項目にCustomPickerContent
と入力します。
Custom Class
が設定されるとそのSwiftファイルにある@IBOutlet
や@IBAction
と関連付けができるようになるので、以下のように関連付けを設定します。
UIPickerViewDelegateでCustomViewを読み込む
最後にViewController側からCustomViewを読み込みます。UIPickerViewDelegate
にある下記のメソッドを用いることでCustomViewを設定できます。
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView
記述する処理は以下のようになります。
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
// Xibファイルを読み込む
let customView = UINib(nibName: "CustomPickerContent", bundle: nil).instantiate(withOwner: nil, options: nil).first as! CustomPickerContent
// 高さを40に固定
customView.frame.size.height = 40
// PickerViewに応じて表示するデータを設定する
if pickerView == foodPickerView {
customView.label.text = foodArray[row]
} else if pickerView == drinkPickerView {
customView.label.text = drinkArray[row]
}
return customView
}
UINib
というクラスより、xib
ファイルに作成したビューを読み込むことができます。
nibName
という引数には読み込みたいXibのファイル名を指定しています。
(また、今回の記事では触れませんが、reusing view: UIView?
という引数には以前にUINib
より作成したビューが格納されているので、そちらを再利用することができます。)
row
引数には対象の要素の行番号は格納されているので、前記事で扱ったようにdrinkArray[row]
やfoodArray[row]
で表示したい文字列を取得できます。
前記事でも説明しましたが、今回はUIPickerView
が一つのViewControllerに二つ存在しているため、if
文を用いてどちらのPickerViewに対して操作をしているかを分岐する必要があります。
完成(再掲)
コード全貌
GitHubにアップロードしました
Discussion