[SWIFT] Create two DatePickers linked with TextField

Introduction

Let's create two UIDatePickers and summarize how to input them to the TextField.

Development environment

macOS Catalina 10.15.7 Xcode 12.1 Swift 5.3

Setting text fields and preparing variables

First, place two text fields anywhere on the StoryBoard. This time, the first text field is ATextField and the second is BTextField.

Also, prepare the following two variables.

ViewController.swift


class ViewController: UIViewController { 
    @IBOutlet weak var ATextField: UITextField!
    @IBOutlet weak var BTextFiled: UITextField!

    var APicker: UIDatePicker!
    var BPicker: UIDatePicker!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
}

Definition of method to create DatePicker

Next, define a method to create a DatePicker to put in the TextField.

ViewController.swift


func makePicker(_ isA:Bool) -> UIDatePicker {
    let myPicker:UIDatePicker!
    myPicker = UIDatePicker()
    myPicker.tag = isA ? 1 : 2
    myPicker.datePickerMode = .date
    myPicker.locale = NSLocale(localeIdentifier: "ja_JP") as Locale
    myPicker.preferredDatePickerStyle = .wheels
        
    return myPicker
}

Since there are two DatePickers to be created, take a form that takes true or false as an argument, and if true, a DatePicker to be inserted into ATextField will be created, and if false, a DatePicker to be inserted into BTextFiled will be created.

Put tags 1 and 2 on each DatePicker. You can freely set the DatePicker in this method.

I referred to this article about the behavior of DatePicker on iOS14. →https://qiita.com/kj_trsm/items/a53b0b3f7e1bc7c06106

Definition of method to detect change of DatePicker

Defines a method that displays the date entered when the DatePicker is manipulated by the user in a text field.

ViewController.swift


@objc internal func dateChanged(sender: UIDatePicker){
     let formatter: DateFormatter = DateFormatter()
     formatter.dateFormat = "yyyy year M month d day"
       
     let selectedDate = formatter.string(from: sender.date)
     if sender.tag == 1 {
         ATextField.text = selectedDate
     } else {
         BTextFiled.text = selectedDate
     }
   
 }

First, prepare a DateFormatter that converts Date type to String type, store the converted character string in the selectedDate variable, and then assign the character string to the input destination text field according to the sender tag.

Once you've done that, addTarget to myPicker in the makePicker method you defined earlier.

ViewController.swift


func makePicker(_ isA:Bool) -> UIDatePicker {
    let myPicker:UIDatePicker!
    myPicker = UIDatePicker()
    myPicker.tag = isA ? 1 : 2
    myPicker.datePickerMode = .date
    myPicker.locale = NSLocale(localeIdentifier: "ja_JP") as Locale
    myPicker.preferredDatePickerStyle = .wheels
       
    //here
    myPicker.addTarget(self, action:  #selector(onDidChangeDate(sender:)), for: .valueChanged)
        
    return myPicker
 }

The process of retracting the keyboard

At this rate, the keyboard will be left unattended when you start operating DatePicker. When you tap outside the keyboard, the keyboard retracts.

ViewController.swift


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    ATextField.endEditing(true)
    BTextFiled.endEditing(true)
}

Create DatePicker in ViewDidLoad

Finally, call the method that creates DatePicker in ViewDidLoad and input it into the text field to complete.

ViewContoller.swift


override func viewDidLoad() {
    super.viewDidLoad()
        
    APicker = makePicker(true)
    ATextField.inputView = APicker
        
    BPicker = makePicker(false)
    BTextFiled.inputView = BPicker
        
    }

Whole code

ViewCOntroller.swift


class ViewController: UIViewController {
    @IBOutlet weak var ATextField: UITextField!
    @IBOutlet weak var BTextFiled: UITextField!
    
    var APicker: UIDatePicker!
    var BPicker: UIDatePicker!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        APicker = makePicker(true)
        ATextField.inputView = APicker
        
        BPicker = makePicker(false)
        BTextFiled.inputView = BPicker
        
    }
    
    func makePicker(_ isA:Bool) -> UIDatePicker {
        let myPicker:UIDatePicker!
        myPicker = UIDatePicker()
        myPicker.tag = isA ? 1 : 2
        myPicker.datePickerMode = .date
        myPicker.locale = NSLocale(localeIdentifier: "ja_JP") as Locale
        myPicker.preferredDatePickerStyle = .wheels
        
        myPicker.addTarget(self, action:  #selector(onDidChangeDate(sender:)), for: .valueChanged)
        
        return myPicker
    }
    
    @objc internal func onDidChangeDate(sender: UIDatePicker){
        let formatter: DateFormatter = DateFormatter()
        formatter.dateFormat = "yyyy year M month d day"
        
        let mySelectedDate = formatter.string(from: sender.date)
        if sender.tag == 1 {
            ATextField.text = mySelectedDate
        } else {
            BTextFiled.text = mySelectedDate
        }
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        ATextField.endEditing(true)
        BTextFiled.endEditing(true)
    }


}

Recommended Posts

Create two DatePickers linked with TextField
Alert with TextField
Try create with Trailblazer
Create a Jar file with two lines of command
Create XML-RPC API with Wicket
Create a playground with Xcode 12
Create microservices with Spring Boot