Search code examples
swiftpopupalertuipickerviewuialertview

how to add uipickerview in uialertview swift 3


Swift 3 iOS 10: I want to add UIPickerView in UIAlertView so that i can choose item and set it's value to the textField. I could do it with UIView but I want to improve it in a better and natural way. Is it possible to do this or any way out?

Thank in advance!

This is what I have done,

Pix1: my textfield: https://z-p3-scontent.fpnh5-1.fna.fbcdn.net/v/t1.0-9/19702221_1969127863363332_1282515913735651533_n.jpg?oh=ece774626e6691c531dc69b168104fcc&oe=59D72E14

Pix2: my alert: https://z-p3-scontent.fpnh5-1.fna.fbcdn.net/v/t1.0-9/19665630_1969127860029999_9139151345242136168_n.jpg?oh=d56be1efc3bd772ff68e7e45fa7ebfae&oe=5A0F290F


Solution

  • Although Apple suggests us not to do so, you can indeed add a picker view to your alert view controller. UIAlertViewController has nothing magic other than a normal view controller. All you need to do is to show title text with lots of new lines (namely "Select\n\n\n\n\n\n\n\n\n\n\n\n") in order to increase the alert height, and then call alertViewController.addSubview(datePicker)

    However the questions is why you need to write extra code to manipulate an alert view controller and handle which text field to set value? Here is another approach that is way easier to maintain and implement.

    First create your picker view and configure it.

    let picker = UIPickerView()
    picker.delegate = self
    picker.dateSource = self
    // configure
    

    Then for each of your text field, simply call this

    tf1.tag = 1
    tf2.tag = 2
    tf3.tag = 3
    
    tf1.delegate = self
    tf2.delegate = self
    tf3.delegate = self
    
    tf1.inputView = picker
    tf2.inputView = picker
    tf3.inputView = picker
    

    Not in your text field delegate method, store which text field user clicked on and reload picker view data

    var tfTag = 0
    
    func textFieldDidBeginEditing(_ textField: UITextField) {
        tfTag = textField.tag
        picker.reloadAllComponents()
    }
    

    Finally in all your picker view data source or delegate method, load different set of data base on the unique tag number from each of the text field

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if tfTag == 0 {
            if component == 0 {
                return "1"
            }else if component == 1 {
                return "2"
            }else if component == 2 {
                return "3"
            }else{
                return "4"
            }
        }else if tfTag == 1 {
            //...
        }else{
            //...
        }
    }