73764


テキストフィールドとピッカーを用いて、カレンダーの月と日を指定するものを作成したいです。現段階では、月を指定するものはできたのですが、もう一つ作る方法がわかりません。どうすればいいでしょうか？もう一つとは、もう一つテキストフィールドを作成して、そこに新しく日にちを選ぶピッカーを作成することです。つまり、テキストフィールド二つで別々にピッカーを作成したいです。

ソースコード

[code]

    import UIKit
    
    class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 1
        }
    
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            return 12
        }
    
        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            return data[row]
        }
    
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            textField.text = data[row]
        }
    
        @IBOutlet weak var textField: UITextField!
        var pickerView = UIPickerView()
        var data = ["1", "2", "3","4", "5", "6","7", "8", "9","10", "11", "12"]
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            createPickerView()
        }
    
        func createPickerView() {
            pickerView.delegate = self
            textField.inputView = pickerView
            // toolbar
            let toolbar = UIToolbar()
            toolbar.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 44)
            let doneButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(ViewController.donePicker))
            toolbar.setItems([doneButtonItem], animated: true)
            textField.inputAccessoryView = toolbar
        }
    
        @objc func donePicker() {
            textField.endEditing(true)
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            textField.endEditing(true)
        }
    }
    
[/code]


CC BY-SA 4.0
2021-02-01T17:49:26.857
73741
2021-02-02T10:45:11.543
2021-02-01T19:32:53.770
18540
43783
question
swift ios iphone
テキストとピッカーを用いた入力


”月”用の`UIPickerView`と、”日”用の`UIPickerView`の二つのインスタンスを作る。そしてこれらをある方法で区別（識別）する。この方向で考えを進めていきます。  
`UIPickerView`の`delegate`、`dataSource`には、一例を挙げると

[code]

    optional func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
    
[/code]

のように、第一引数に委譲元の`UIPickerView`のインスタンスをとります。この引数を使えば、`if`文で、二つの`UIPickerView`の識別を行うことができます。  
そして、`UIPickerView`の識別は、親クラスである`UIView`のプロパティ`tag`を使ってできます。

[UIView -
tag](https://developer.apple.com/documentation/uikit/uiview/1622493-tag)

この方針に基づくと、ご掲載のコードは、このように書き換えることができます。

[code]

    import UIKit
    
    class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    
        @IBOutlet weak var textField1: UITextField!
        @IBOutlet weak var textField2: UITextField!
    
        var pickerView1: UIPickerView!
        var pickerView2: UIPickerView!
        var data1: [String]!
        var data2: [String]!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            data1 = [Int](1...12).map { String($0) }
            data2 = [Int](1...31).map { String($0) }
            pickerView1 = UIPickerView()
            pickerView2 = UIPickerView()
            createPickerViews()
        }
    
        func createPickerViews() {
            pickerView1.dataSource = self
            pickerView1.delegate = self
            pickerView1.tag = 1 // Caution!
            textField1.inputView = pickerView1
            
            pickerView2.dataSource = self
            pickerView2.delegate = self
            pickerView2.tag = 2 // Caution!
            textField2.inputView = pickerView2
            // toolbar
            let toolbar = UIToolbar()
            toolbar.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 44)
            let doneButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(ViewController.donePicker))
            toolbar.setItems([doneButtonItem], animated: true)
            textField1.inputAccessoryView = toolbar
            textField2.inputAccessoryView = toolbar
        }
    
        @objc func donePicker() {
            textField1.endEditing(true)
            textField2.endEditing(true)
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            textField1.endEditing(true)
            textField2.endEditing(true)
        }
        
        // Picker View's Delegates & DataSources
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 1
        }
    
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            if pickerView.tag == 1 {
                return 12
            } else {
                return 31
            }
        }
    
        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            if pickerView.tag == 1 {
                return data1[row]
            } else {
                return data2[row]
            }
        }
    
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            if pickerView.tag == 1 {
                textField1.text = data1[row]
            } else {
                textField2.text = data2[row]
            }
        }
    }
    
[/code]

コメント`// Caution!`の行で、`pickerView1`、`pickerView2`の`tag`を指定しています。

* * *

これで、「つまり、テキストフィールド二つで別々にピッカーを作成」することはできますが、問題の解決には至ってないことは、明らかだと思います。月の大小（31日まで、30日まで）、閏年の2月（28日まで、29日まで）など、対処しなければならない課題は残ったままです。もし私がプログラムを書くとしたら、コメント欄でOOPerさんがおっしゃるように、`UIDatePicker`を使うでしょう。


CC BY-SA 4.0
2021-02-02T10:45:11.543
73764
2021-02-02T10:45:11.543
18540
73741
answer