29

I am trying to create a text box that when it is selected a UIPickerView opens up with choices to select from. Once selected, the UIPickerView hides and the selected item is displayed in the text box. I tried different pieces of code I found online but I just can't get it to work. If someone can suggest a complete code for this or tell me what I am doing wrong in my code, that would be super awesome. Thanks so much.

Here is my code:

@IBOutlet var textfieldBizCat: UITextField!
@IBOutlet var pickerBizCat: UIPickerView! = UIPickerView()

var bizCat = ["Cat One", "Cat Two", "Cat Three"]


override func viewDidLoad() {
    super.viewDidLoad()

    var bizCatCount = bizCat.count

    self.textfieldBizCat.inputView = pickerView

}

// returns the number of 'columns' to display.
func numberOfComponentsInPickerView(pickerView: UIPickerView!) -> Int{
    return 1
}

// returns the # of rows in each component..
func pickerView(pickerView: UIPickerView!, numberOfRowsInComponent component: Int) -> Int{
    return bizCat.count
}

func pickerView(pickerView: UIPickerView!, titleForRow row: Int, forComponent component: Int) -> String! {
    return bizCat[row]
}

func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int)
{
    textfieldBizCat.text = "\(bizCat[row])"

}
Dan Beaulieu
  • 19,406
  • 19
  • 101
  • 135
TimberWebDesign
  • 365
  • 2
  • 4
  • 10

4 Answers4

49

If I understood well your question, you want:

  1. Have an UITextField which display a text selected
  2. Opening a picker when the user click on the UITextField
  3. Close the picker when an item (in the picker) is selected, and set it in the UITextField

This is the complete code to manage it, you just have to link the delegate of your UITextField:

@IBOutlet var textfieldBizCat: UITextField!
@IBOutlet var pickerBizCat: UIPickerView! = UIPickerView()

var bizCat = ["Cat One", "Cat Two", "Cat Three"]


override func viewDidLoad() {
    super.viewDidLoad()
    pickerBizCat.hidden = true;
    textfieldBizCat.text = bizCat[0]
}

// returns the number of 'columns' to display.
func numberOfComponentsInPickerView(pickerView: UIPickerView!) -> Int{
    return 1
}

// returns the # of rows in each component..
func pickerView(pickerView: UIPickerView!, numberOfRowsInComponent component: Int) -> Int{
    return bizCat.count
}

func pickerView(pickerView: UIPickerView!, titleForRow row: Int, forComponent component: Int) -> String! {
    return bizCat[row]
}

func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int)
{
    textfieldBizCat.text = bizCat[row]
    pickerBizCat.hidden = true;
}

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
    pickerBizCat.hidden = false
    return false
}

What I changed from your code:

  • Used UITextFieldDelegate to display the picker when the UITextField is selected
  • Hide the picker once an item is selected, and setup the UITextField
  • Set the first row of your picker in the UITextField when any item is selected
Ronan Boiteau
  • 9,608
  • 6
  • 34
  • 56
tbaranes
  • 3,560
  • 1
  • 23
  • 31
  • Thank you for your help Ckouta. It now displays "Cat One" in the text field, but when I click on it, the UIPicker is not appearing. – TimberWebDesign Nov 08 '14 at 17:41
  • 1
    Did you set the UITextField delegate from your xib? You can do it also programatically, just add `textfieldBizCat.delegate = self`in `viewDidLoad` – tbaranes Nov 08 '14 at 17:43
  • Oh, ok forgot to do that. Also needed to add pickerBizCat.delegate = self to viewDidLoad. Now it works! Thanks so much. – TimberWebDesign Nov 08 '14 at 18:50
  • how would this be modified if you have multiple textfields you want to add a picker to in that view @Ckouta – kareem Feb 11 '15 at 03:54
  • That is a another question, I suggest you to ask a new question on stack directly with your actual source code, issue... – tbaranes Feb 11 '15 at 07:37
  • Hi, when I follow your examples I get the error "RegisterViewController does not conform to protocoll UITextDelegate" This error shows when I enter the line with textfieldName.delegate = self. Any help on that? – user1555112 Feb 20 '15 at 13:01
  • @tbaranes can you explain why it's better to use the UITextFieldDelegate textFieldShouldBeginEditing method to display the pickerView vice setting the textfield's inputView = pickerView? Or does it not make a difference? – A. Vin May 03 '16 at 18:36
  • http://stackoverflow.com/questions/30495585/swift-hide-pickerview-after-value-selected – Kyaw Min Thu L Jun 21 '16 at 12:38
3

Swift 4 version

override func viewDidLoad() {
    super.viewDidLoad()

    pickerView.dataSource = self
    pickerView.delegate = self

    textField.delegate = self
    textField.inputView = pickerView
}

And the extensions

// MARK: - UIPickerViewDelegate

extension ViewController: UITextFieldDelegate {

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        pickerView.isHidden = false
        return false
    }
}

// MARK: - UIPickerViewDelegate

extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return myItems.count
    }

    func pickerView( _ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return myItems[row].name
    }

    func pickerView( _ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        textField.text = myItems[row].name
        pickerView.isHidden = true
    }
}
Tomas
  • 866
  • 16
  • 21
1

How about in your didSelectRow method you resignFirstResponder?

func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int)
{
textfieldBizCat.text = bizCat[row]
pickerBizCat.resignFirstResponder()
}
Tim Denison
  • 171
  • 1
  • 2
  • 13
0
  // pressing the button again would hide the uipickerview. when pressed the first time, update the button's label to "done" , "hide" or whatever suits u!
    @IBAction func propertyTypeButtonPressed(sender: UIButton)/* the name of your button's action*/
    {
        count++; //declare it first
        ViewContainigPickerView.hidden = false
        self.view.endEditing(true)

        if (count == 2)
        {
            ViewContainingPickerView.hidden = true /* if you placed your picker on a separate view for simplicity*/
            count = 0;

        }

    }
Quentin Hayot
  • 7,786
  • 6
  • 45
  • 62