Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

resignFirstResponder for UIPicker in UITextField Swift

I want the UIPickerView to be dismissed (slide out of view) after the done button is clicked on the toolbar. I've linked the UIPickerView as the inputView of the UITextField and set the UIToolbar as the inputAccessoryView of the UIPickerView. However, my function calling resignFirstResponder does not slide the UIPicker out of the view. Any help is appreciated and thanks in advance!

import UIKit

class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
    // Do any additional setup after loading the view, typically from a nib.

    //initialization constants
    let pickerView = UIPickerView()
    let textField = UITextField()
    let pickerData = ["1","2","three"]


    override func viewDidLoad() {
        //pickerview tool bar
        let toolbar = UIToolbar(frame: CGRectMake(0, 0, 320, 44))
        var items = [AnyObject]()
        //making done button
        let doneButton = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: Selector(donePressed()))
        items.append(doneButton)
        toolbar.barStyle = UIBarStyle.Black
        toolbar.setItems(items, animated: true)


        //creating textfields with a pickerview
        pickerView.delegate = self
        pickerView.dataSource = self
        pickerView.frame = CGRectMake(0, 0, 500, 300)
        textField.inputAccessoryView = toolbar
        textField.inputView = pickerView
        textField.frame = CGRectMake(200, 55, 100, 35)
    textField.backgroundColor = UIColor.blueColor()

    //adding objs to viewController
    self.view.addSubview(textField)
}

func donePressed() {
    resignFirstResponder()
}





override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}



}

//MARK: Data Sources UIPickerView
extension ViewController: UIPickerViewDataSource {
    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return 1
    }
    func pickerView(pickerView: UIPickerView!, numberOfRowsInComponent component: Int) -> Int {
        return pickerData.count
    }
}

//MARK: Delegates UIPickerView
extension ViewController: UIPickerViewDelegate {
    // several optional methods:




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

func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) {
    textField.text = pickerData[row]
}
}
like image 461
Linus Liang Avatar asked Oct 26 '14 12:10

Linus Liang


1 Answers

There are 2 problems:

  1. Your selector for donePressed is declared incorrectly. It should be:

    let doneButton = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: "donePressed")
    
  2. You need to call resignFirstResponder() on textField:

    func donePressed() {
        textField.resignFirstResponder()
    }
    

If you have multiple textFields, and you don't want to hardcode the textField in the resignFirstResponder call, you can do the following:

  1. Make your ViewController a UITextFieldDeletate:

    class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate {
    
  2. Set the delegate property on your UITextField:

    textField.delegate = self
    
  3. Add a property to your ViewController to keep track of the active UITextField:

    var activeTextField:UITextField?
    
  4. Implement textFieldDidBeginEditing and store the active UITextField:

    func textFieldDidBeginEditing(textField: UITextField) { // became first responder
        activeTextField = textField
    }
    
  5. In donePressed, call resignFirstResponder on activeTextField:

    func donePressed() {
        activeTextField?.resignFirstResponder()
    }
    
like image 117
vacawama Avatar answered Sep 19 '22 21:09

vacawama