When I tap outside my UITextField
to clear it's content and hide the keyboard it reacts as if I hit return
and triggers actions associated with hitting return
. It seems pretty counterintuitive to me.
The textField cleared and keyboard dismissed I want, but not amountEntered(_:)
called.. I want to be able to abort any action when I tap outside the textField
How can I change that?
All the code related to the TextField
:
override func viewDidLoad() {
super.viewDidLoad()
amountEnteredTextField.delegate = self
registerForKeyboardNotifications()
self.hideKeyboard()
}
func textFieldShouldReturn(_ scoreText: UITextField) -> Bool {
self.view.endEditing(true)
return true
}
@IBAction func amountEntered(_ sender: UITextField) {
if allowNewAmount == true {
if amountEnteredTextField.text == "" {
return
}
amountLabel.text = amountEnteredTextField.text
amountEnteredTextField.text = ""
}
}
After debugging, the issue seems to be coming from this extension used to hide the keyboard:
extension UIViewController {
func hideKeyboard() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
}
@objc func dismissKeyboard() {
view.endEditing(true)
}
}
So it seems your amountEntered(_:)
is called anytime amountEnteredTextField
ends editing. This is due to you setting it up as an IBAction
for the event .editingDidEnd
.
In hideKeyboard()
, you have set up a tap gesture on self.view
linked to dismissKeyboard()
that does view.endEditing(true)
.
This basically resigns any first responder; meaning amountEnteredTextField
editing ends and hence amountEntered(_:)
is called when you tap outside.
If you want to ensure amountEntered(_:)
is called only when the user taps on the keyboard's return key then you should modify your design a little bit as so:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
/*
Check to see which is the delegated textField.
Basically to do textField-specific logic.
Helps mostly if you have multiple textFields
*/
if textField == amountEnteredTextField {
amountEntered()
}
//resign textField
textField.resignFirstResponder()
return true
}
func amountEntered() {
if allowNewAmount, amountEnteredTextField.text != "" {
amountLabel.text = amountEnteredTextField.text
amountEnteredTextField.text = ""
}
}