JY-CONTENTS

JY

JY-CONTENTS
search

+

MENU

【Swift/ios】UIPickerViewクラス

【Swift/ios】UIPickerViewクラス

(DATE)

-

2018.01.06

(CATEGORY)

-

//ViewControllerクラスでUIPickerViewのデリゲートメソッドを使用するため
//UIPickerViewDelegate, UIPickerViewDataSourceの2つのプロトコルを採用する
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    @IBOutlet weak var myPicker: UIPickerView!
    
    let compos = [["月","火","水","木","金"], ["午前","午後"]]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //ViewControllerクラスをmyPickerのデリゲート、データソースに指定
        //これでViewControllerクラス内でUIPickerViewのデリゲートメソッドが使用できる
        myPicker.delegate = self
        myPicker.dataSource = self
    }
    
    //---------------データソース----------------------------
    //ピッカーの個数の指定
    public func numberOfComponents(in pickerView: UIPickerView) -> Int{
        return compos.count
    }
    
    //各ピッカーの行数の指定
    //第2引数(component):配列のインデックス
    public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
        let compo = compos[component]
        return compo.count
    }
    
    //---------------デリゲート------------------------------
    //各ピッカーの横幅の指定
    //第2引数(component):配列のインデックス
    func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
        if component == 0 {
            return 50
        }else {
            return 100
        }
    }
    
    //各ピッカーに配列の項目を指定(設定)する
    //第2引数(row):配列の配列の値のインデックス
    //第3引数(component):配列のインデックス
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        let item = compos[component][row]
        return item
    }
    
    //選択された項目を調べる
    //第2引数(row):選択された値(配列の配列の値)のインデックス
    //第3引数(component):選択された項目(配列)のインデックス
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        //選択された値
        let item = compos[component][row]
        print(item, "が選ばれた")
        
        //1つ目のコンポーネント(ピッカー)の行
        let row1 = pickerView.selectedRow(inComponent: 0)
        //2つ目のコンポーネント(ピッカー)の行
        let row2 = pickerView.selectedRow(inComponent: 1)
        print("現在選択されている行番号: \(row1, row2)")
        
        //選択されている項目名
        //1つ目のコンポーネント(ピッカー)の現在選択されている項目名
        let item1 = self.pickerView(pickerView, titleForRow:row1, forComponent:0)
        //2つ目のコンポーネント(ピッカー)の現在選択されている項目名
        let item2 = self.pickerView(pickerView, titleForRow:row2, forComponent:1)
        print("現在選択されている項目名: \(item1, item2)")
    }
    
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

プロトコルの採用

ViewControllerクラスでUIPickerViewのデリゲートメソッドを使用するため
UIPickerViewDelegate, UIPickerViewDataSourceの2つのプロトコルを採用します。

この箇所についてはUIPickerViewクラスに限らず、その他のイベント発生においても、イベント発生時の処理を設定したい場合はそのイベント(クラス)のデリゲート及びデータソースのプロトコルををデリゲートメソッドを記述したクラス(今回はViewControllerクラス)に採用します。

デリゲートメソッド、データソースメソッドを記述するクラスを指定

override func viewDidLoad() {
   super.viewDidLoad()
   //ViewControllerクラスをmyPickerのデリゲート、データソースに指定
   //これでViewControllerクラス内でUIPickerViewのデリゲートメソッドが使用できる
   myPicker.delegate = self
   myPicker.dataSource = self
}

storyboard上に配置してあるmyPicker(outlet接続した)のイベント発生時の処理を記述する(デリゲートメソッド、データソースメソッド)クラスを設定します。
今回はViewControllerクラスを使用するためselfを設定しています。
UIPickerViewDelegate, UIPickerViewDataSourceのプロトコルを採用しているクラスであれば設定できます。

この箇所も上記と同じく、その他のイベント発生においても、同様の記述設定をします。

データソースメドッド

基本的にはデータに関することを取り扱うメソッドです。

//---------------データソース----------------------------
    //ピッカーの個数の指定
    public func numberOfComponents(in pickerView: UIPickerView) -> Int{
        return compos.count
    }
    
    //各ピッカーの行数の指定
    //第2引数(component):配列のインデックス
    public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
        let compo = compos[component]
        return compo.count
    }

ピッカーの個数の指定

//ピッカーの個数の指定
public func numberOfComponents(in pickerView: UIPickerView) -> Int{
   return compos.count
}

ピッカーの個数を設定します。
今回は下記のような配列の内容をピッカーに反映させるので、配置するピッカーの数は
「月〜金」を表示させるピッカーと「午前、午後」を表示させるピッカーの2個です。

let compos = [["月","火","水","木","金"], ["午前","午後"]]

各ピッカーの行数の指定

//各ピッカーの行数の指定
//第2引数(component):配列のインデックス
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
    let compo = compos[component]
    return compo.count
}

第2引数(component): ピッカーのインデックス

各ピッカーの行数の設定します。
第2引数はピッカーのインデックス番号になります。
今回の場合はピッカーの個数は2個なので、pickerView( numberOfRowsInComponent)が最初に呼び出され時はcomponentには「0」が2回目に呼び出された時には「1」が入ります。

下記でピッカーを一つずつ配列composから取り出しcompo.countで各ピッカーの要素(値)を指定します。

let compo = compos[component]
return compo.count

今回の場合は、
compos[0]・・・・[“月”,”火”,”水”,”木”,”金”]
compos[1]・・・・[“午前”,”午後”]
となり、そのcountなので「5」と「2」になります。

デリゲートメソッド

基本的にはイベント処理に関することを取り扱うメソッドです。

//---------------デリゲート------------------------------
//各ピッカーの横幅の指定
//第2引数(component):配列のインデックス
func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
   if component == 0 {
       return 50
   }else {
       return 100
   }
}
    
//各ピッカーに配列の項目を指定(設定)する
//第2引数(row):配列の配列の値のインデックス
//第3引数(component):配列のインデックス
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
   let item = compos[component][row]
   return item
}
    
//選択された項目を調べる
//第2引数(row):選択された値(配列の配列の値)のインデックス
//第3引数(component):選択された項目(配列)のインデックス
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
   //選択された値
   let item = compos[component][row]
   print(item, "が選ばれた")
        
   //1つ目のコンポーネント(ピッカー)の行
   let row1 = pickerView.selectedRow(inComponent: 0)
   //2つ目のコンポーネント(ピッカー)の行
   let row2 = pickerView.selectedRow(inComponent: 1)
   print("現在選択されている行番号: \(row1, row2)")
        
   //選択されている項目名
   //1つ目のコンポーネント(ピッカー)の現在選択されている項目名
   let item1 = self.pickerView(pickerView, titleForRow:row1, forComponent:0)
   //2つ目のコンポーネント(ピッカー)の現在選択されている項目名
   let item2 = self.pickerView(pickerView, titleForRow:row2, forComponent:1)
   print("現在選択されている項目名: \(item1, item2)")
}

今回使用するデリゲートメソッドは上記の3つです。

ピッカーの横幅の指定

//各ピッカーの横幅の指定
//第2引数(component):配列のインデックス
func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
   if component == 0 {
       return 50
   }else {
       return 100
   }
}

今回はピッカーは2個なので第2引数(component)の値(インデックス)は「0」と「1」です。
compos[0]・・・・[“月”,”火”,”水”,”木”,”金”]
compos[1]・・・・[“午前”,”午後”]
なので、
●[“月”,”火”,”水”,”木”,”金”]の配列が反映されるピッカーの横幅は「50」
●[“午前”,”午後”]の配列が反映されるピッカーの横幅は「100」
になります。

各ピッカーに配列の項目を指定(反映)する

//各ピッカーに配列の項目を指定(設定)する
//第2引数(row):配列の配列の値のインデックス
//第3引数(component):配列のインデックス
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
   let item = compos[component][row]
   return item
}

・・・今回は[“月”,”火”,”水”,”木”,”金”]と[“午前”,”午後”]なので「0〜4」と「0〜1」。

・・・・各ピッカーのインデックス。今回は2個なので「0」と「1」。

組み合わせは(0、0〜4)と(1、0〜1)。

選択された項目を調べる

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
   //選択された値
   let item = compos[component][row]
   print(item, "が選ばれた")
        
   //1つ目のコンポーネント(ピッカー)の行
   let row1 = pickerView.selectedRow(inComponent: 0)

   //2つ目のコンポーネント(ピッカー)の行
   let row2 = pickerView.selectedRow(inComponent: 1)
   print("現在選択されている行番号: \(row1, row2)")
        
   //選択されている項目名
   //1つ目のコンポーネント(ピッカー)の現在選択されている項目名
   let item1 = self.pickerView(pickerView, titleForRow:row1, forComponent:0)

   //2つ目のコンポーネント(ピッカー)の現在選択されている項目名
   let item2 = self.pickerView(pickerView, titleForRow:row2, forComponent:1)
   print("現在選択されている項目名: \(item1, item2)")

   print("------------------")
}

ドラムが回転して項目が選ばれると上記のpickerView(_ didSelectRow: inComponent:)メソッドが呼び出さ、コンポーネントで選ばれた行とコンポーネント番号が引数で送られてきます。

selectedRow(inComponent:)メソッドを使えばコンポーネントで選ばれている行を調べることもできます。

pickerView(_:titleForRow)メソッドを使えば、コンポーネントで現在選ばれている項目名を調べることができます。

上記スクリプトの出力結果

//1つ目のピッカーを回した結果
火 が選ばれた
現在選択されている行番号: (1, 0)
現在選択されている項目名: ("火", "午前")
------------------

//2つ目のピッカーを回した結果
昼間 が選ばれた
現在選択されている行番号: (1, 1)
現在選択されている項目名: ("火", "昼間")
------------------
出力結果

NEW TOPICS

/ ニュー & アップデート

SEE ALSO

/ 似た記事を見る

JY CONTENTS UNIQUE BLOG

search-menu search-menu