Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextField doesn't end editing when Button clicked( delegate textFieldDidEndEditing )

I have two textFields on the screen and a Submit button. User inputs details in first textField and then the second one.

My requirement is to end the editing when Submit button is clicked and print the user inputs in these textFields.I am having issues printing the second textField's value, as the editing never seems to end when the user clicks the Submit button.

Here is my code. Appreciate your help on this issue (I have added the textfield delegate)

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    var firstName = ""
    var lastName = ""

    @IBOutlet var buttonUI: UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func Submit(sender: UIButton) {

        print(firstName)
        print(lastName)

    }

    func textFieldDidEndEditing(textField: UITextField) {

        switch textField.tag {

        case 1:
              firstName = textField.text!
            print(firstName)
        case 2:

            lastName = textField.text!
            print(lastName)

        default: break
        }

    }


}
like image 649
Naishta Avatar asked Dec 16 '15 22:12

Naishta


2 Answers

Within your ViewController class, for each textfield, create an @IBOutlet property by Ctrl-dragging each text field from the storyboard to your code

@IBOutlet weak var textFieldFirst: UITextField!
@IBOutlet weak var textFieldSecond: UITextField!

Also create a private UITextField property to hold the (possibly) current (/most recently used) text field.

private var currentTextField: UITextField?

Override the viewDidLoad method of your UIViewController subclass to initialize the delegates for the two "public" text field instances

override func viewDidLoad() {
    super.viewDidLoad()

    // Handle the user input in the text fields through delegate callbacks (and set tags)
    textFieldFirst.delegate = self
    textFieldFirst.tag = 1
    textFieldSecond.delegate = self
    textFieldSecond.tag = 2
}

Moreover, use the two textFieldShouldReturn(...) and textFieldDidBeginEditing(...) methods of the UITextFieldDelegate to resign the (active) text fields status's as first responder and to update the currentTextField reference, respectively.

// UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
    // User finished typing (hit return): hide the keyboard.
    textField.resignFirstResponder()
    return true
}

func textFieldDidBeginEditing(textField: UITextField) {
    currentTextField = textField
}

Finally, resign any possibly current text field as first responder, in case submit is pressed in-middle-of editing

@IBAction func Submit(sender: UIButton) {
    if let currentTextField = currentTextField {
        currentTextField.resignFirstResponder()
    }
    print(firstName)
    print(lastName)
}

With this, your view controller should work as intended.


To summarize: after the additions and modifications above, your ViewController class should look like

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    // Properties
    @IBOutlet weak var textFieldFirst: UITextField!
    @IBOutlet weak var textFieldSecond: UITextField!
    private var currentTextField: UITextField?
    var firstName = ""
    var lastName = ""

    @IBOutlet var buttonUI: UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    // Actions
    @IBAction func Submit(sender: UIButton) {
        if let currentTextField = currentTextField {
            currentTextField.resignFirstResponder()
        }
        print(firstName)
        print(lastName)
    }

    // viewDidLoad
    override func viewDidLoad() {
        super.viewDidLoad()

        // handle the user input in the text fields through delegate callbacks
        textFieldFirst.delegate = self
        textFieldSecond.delegate = self

        // tags
        textFieldFirst.tag = 1
        textFieldSecond.tag = 2
    }

    // UITextFieldDelegate
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        // User finished typing (hit return): hide the keyboard.
        textField.resignFirstResponder()
        return true
    }

    func textFieldDidBeginEditing(textField: UITextField) {
        currentTextField = textField
    }

    func textFieldDidEndEditing(textField: UITextField) {
        switch textField.tag {
        case 1:
            firstName = textField.text!
            print(firstName)
        case 2:
            lastName = textField.text!
            print(lastName)
        default: break
        }
    }
}
like image 186
dfrib Avatar answered Oct 07 '22 13:10

dfrib


What do you mean by

I am having issues printing the 2nd textfield's user inputs, as the editing never gets ended when user clicks the Submit.

Why not just read the values in textfields when the users presses submit? Make sure your outlets and delegates are correct.

Make an action to your button Touch up inside and in that button you´ll read the values:

firstName = textFieldOne.text
lastName = textFieldTwo.text
like image 37
Rashwan L Avatar answered Oct 07 '22 15:10

Rashwan L