在 UITextField 外部点击以停止编辑

Tapping outside a UITextField to stop editing

当我点击 UITextField 外部以清除其内容并隐藏键盘时,它的反应就像我点击 return 并触发与点击 return 相关的操作。这对我来说似乎很违反直觉。

我想要清除文本字段并关闭键盘,但没有调用 amountEntered(_:)。我希望能够在点击 [=] 外部时 中止 任何操作16=]

我该如何改变它?

所有与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 = ""

    }
}

调试后,问题似乎出在这个用于隐藏键盘的扩展:

extension UIViewController {

    func hideKeyboard() {

        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))

        view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard() {
       view.endEditing(true)
    }
}

您可以在 Tap action responder 中使用 view.endEditing(true),这将调用您的 textFieldDidEndEditing: 委托方法。而不是 textFieldShouldReturn 代表 UITextField.

所以您的 amountEntered(_:) 似乎随时被调用 amountEnteredTextField 结束编辑。这是因为您将其设置为事件 .editingDidEnd.

IBAction

hideKeyboard() 中,您在链接到 dismissKeyboard()self.view 上设置了点击手势 view.endEditing(true)。 这基本上会让任​​何第一响应者辞职;意思是 amountEnteredTextField 编辑结束,因此当您点击外部时会调用 amountEntered(_:)

如果你想确保 amountEntered(_:) 只在用户点击键盘的 return 键时被调用,那么你应该像这样稍微修改你的设计:

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 = ""            
    }
}