【Swift5】pickerViewを2つ(以上)とdatePickerを設置して下から出るようにする。

定期的にpickerViewのこんな記事を書いている気がします。(^_^;)
pickerViewはよく使うけどアプリをたまにしか作らないのでその間にSwiftのバージョンも上がるし作り方も忘れるよね。

同じViewContorollerに2つ以上のPickerViewを設置し、datePickerも使って、しかも普通のキーボードのように下から出るようにしたい。
それに少し前の記事を参考に閉じるボタンも付けます。それは下記参照。
【Swift5】textFieldのキーボードに閉じるボタンを付ける。 | iPhoneアプリ備忘録

ではまず、3つのtextfieldを作成します。
autoLayoutは適当に。
スクリーンショット 2020-04-11 11.06.09

textfieldはそれぞれあうとれっとせつぞくします。
pickerViewのプロパティを2つと、datePickerのプロパティを作り、pickerViewに表示する配列も作成します。

UIPickerViewDelegate, UIPickerViewDataSourceを設定するとプロトコルに従いメソッドが作成されます。
UITextFieldDelegateも書いておきましょう。
とりあえずここまでのコード。

import UIKit

class ViewController: UIViewController,UITextFieldDelegate,UIPickerViewDelegate, UIPickerViewDataSource {

    //textFieldとのアウトレット接続
    @IBOutlet weak var kanaTextField: UITextField!
    @IBOutlet weak var numberTextField: UITextField!
    @IBOutlet weak var dateTextField: UITextField!

    //pickerViewのプロパティを作る
    var kanaPickerView : UIPickerView = UIPickerView()
    var numberPickerView  : UIPickerView = UIPickerView()
    //datePickerのプロパティを作る
    var datePickerView  :UIDatePicker = UIDatePicker()
    
    //pickerViewに表示する配列を作成
    let list1:[String] = ["いち","に","さん","よん","ご",]
    let list2:[String] = ["1","2","3","4","5","6","7"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        <#code#>
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        <#code#>
    }
}

そして、プロトコルは置いといてキーボードをpickerViewに置き換える辺りの設定します。
基本的にはPickerViewにtagを設定し、textfieldのinputViewに設定します。
datePickerも同様に。
viewDidLoadから呼びます。

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        makePickerKeybord()
    }
    
    //キーボードの設定
    func makePickerKeybord(){
        //かな数字のPickerviewをキーボードにする設定
        kanaPickerView.tag = 1
        kanaPickerView.delegate = self
        kanaTextField.inputView = kanaPickerView
        kanaTextField.delegate = self
        
        //numberのPickerviewをキーボードにする設定
        numberPickerView.tag = 2
        numberPickerView.delegate = self
        kanaTextField.inputView = numberPickerView
        kanaTextField.delegate = self
        
        // 日付ピッカーをキーボードにする設定
        datePickerView.datePickerMode = UIDatePicker.Mode.dateAndTime
        datePickerView.timeZone = TimeZone(identifier: "Asia/Tokyo")
        datePickerView.locale = Locale(identifier: "ja_JP")
        datePickerView.minuteInterval = 15
        datePickerView.addTarget(self, action: Selector(("dateChange")), for: .valueChanged)
        dateTextField.inputView = datePickerView
        dateTextField.delegate = self
    }

pickerViewのプロトコルの設定。
コンポーネントの数は1でコンポーネントに入る配列の数はtagで切り分けます。
コンポーネントの中身、配列もtagで切り分け。

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        switch pickerView.tag {
        case 1:
            return list1.count
        case 2:
            return list2.count
        default:
            return 0
        }
    }
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        print("たぐ",pickerView.tag)
        switch pickerView.tag {
            case 1:
                return list1[row]
            case 2:
                return list2[row]
        default:
            return "error"
        }
    }

pickerViewとdatePickerViewに変更があった時に呼ばれてtextFieldのテキストが書き換えられるメソッド。

     //pickerが選択された際に呼ばれるデリゲートメソッド.
     func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
         switch pickerView.tag {
             case 1:
                 return kanaTextField.text = list1[row]
             case 2:
                 return numberTextField.text = list2[row]
         default:
             return
         }
     }
     
     //datePickerが変化すると呼ばれる
    @objc func dateChange(){
         let formatter = DateFormatter()
         formatter.dateFormat = "yyyy年MM月dd日 HH:mm"
         dateTextField.text = "\(formatter.string(from: datePickerView.date))"
     }
}

いちおこれで完成。
IMG_6322

一応全コード

import UIKit

class ViewController: UIViewController,UITextFieldDelegate,UIPickerViewDelegate, UIPickerViewDataSource {

    //textFieldとのアウトレット接続
    @IBOutlet weak var kanaTextField: UITextField!
    @IBOutlet weak var numberTextField: UITextField!
    @IBOutlet weak var dateTextField: UITextField!

    //pickerViewのプロパティを作る
    var kanaPickerView : UIPickerView = UIPickerView()
    var numberPickerView  : UIPickerView = UIPickerView()
    //datePickerのプロパティを作る
    var datePickerView  :UIDatePicker = UIDatePicker()
    
    //pickerViewに表示する配列を作成
    let list1:[String] = ["いち","に","さん","よん","ご",]
    let list2:[String] = ["1","2","3","4","5","6","7"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        makePickerKeybord()
    }
    
    //キーボードの設定
    func makePickerKeybord(){
        //かな数字のPickerviewをキーボードにする設定
        kanaPickerView.tag = 1
        kanaPickerView.delegate = self
        kanaTextField.inputView = kanaPickerView
        kanaTextField.delegate = self
        
        //numberのPickerviewをキーボードにする設定
        numberPickerView.tag = 2
        numberPickerView.delegate = self
        numberTextField.inputView = numberPickerView
        numberTextField.delegate = self
        
        // 日付ピッカーをキーボードにする設定
        datePickerView.datePickerMode = UIDatePicker.Mode.dateAndTime
        datePickerView.timeZone = TimeZone(identifier: "Asia/Tokyo")
        datePickerView.locale = Locale(identifier: "ja_JP")
        datePickerView.minuteInterval = 15
        datePickerView.addTarget(self, action: Selector(("dateChange")), for: .valueChanged)
        dateTextField.inputView = datePickerView
        dateTextField.delegate = self
    }
    
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        switch pickerView.tag {
        case 1:
            return list1.count
        case 2:
            return list2.count
        default:
            return 0
        }
    }
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        switch pickerView.tag {
            case 1:
                return list1[row]
            case 2:
                return list2[row]
        default:
            return "error"
        }
    }
    
     //pickerが選択された際に呼ばれるデリゲートメソッド.
     func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
         switch pickerView.tag {
             case 1:
                 return kanaTextField.text = list1[row]
             case 2:
                 return numberTextField.text = list2[row]
         default:
             return
         }
     }
     
     //datePickerが変化すると呼ばれる
    @objc func dateChange(){
         let formatter = DateFormatter()
         formatter.dateFormat = "yyyy年MM月dd日 HH:mm"
         dateTextField.text = "\(formatter.string(from: datePickerView.date))"
     }
}

// MARK: - キーボードにと閉じるボタンを付ける
//storybordで該当テキストフィールドを選択し、identity Inspectorでclassを DoneTextFierdに切り替える
class DoneTextFierd: UITextField{

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    private func commonInit(){
        let tools = UIToolbar()
        tools.frame = CGRect(x: 0, y: 0, width: frame.width, height: 40)
        let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
        let closeButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.closeButtonTapped))
        tools.items = [spacer, closeButton]
        self.inputAccessoryView = tools
    }

    @objc func closeButtonTapped(){
        self.endEditing(true)
        self.resignFirstResponder()
    }
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です