Swift: 无法让 UITextField 关闭键盘

Swift: Can't get UITextField to dismiss keyboard

我的 VC 中有两个 textFields 和一个 Done 按钮,但我在结束编辑时遇到了一些问题。

当我进入另一个 textField 之后点击一个 textField 时,或者当我在 textField 外部点击时(因为我在父视图中添加了点击识别器),我的 textFieldDidEndEditing 方法被调用但不是当我点击 Done 按钮时。

而且,最重要的是(尤其是当我在实际设备上 运行 时),键盘在任何这些情况下都不会消失,即使我的 textFieldDidEndEditing 方法调用 resignFirstResponder().

为什么键盘没有消失?另外,有没有办法让 textFieldDidEndEditing 在我自动点击字段外时被调用(而不是来自点击识别器)?看起来应该是这样的,但如果我错了,我就错了。

这是我的代码的一些相关部分。

1.Trying 关闭键盘。此方法的第一部分起作用,并存储值(即在调用该方法时)。光标在任何时候都不会从 textField 中消失,键盘也不会消失。

        func textFieldDidEndEditing(_ textField: UITextField) {
    if let playerName = textField.text, let playerNum = nameFields.index(of: textField) {
        playerNames[playerNum] = playerName
    }
    resignFirstResponder()
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    textFieldDidEndEditing(textField)
    return true
}

此外,还有一件奇怪的事情:当我在 textFieldDidEndEditing 中设置断点并调试时,在一个字段中输入一个值并点击 Done,它会转到下一个场景,并且 然后停在textFieldDidEndEditing,此时没有效果(值可能会被存储,但不会反映在新场景中)。

2.Trying 将点击识别器添加到完成按钮。我的代码中没有完成按钮的出口,只是出于懒惰,所以这可能是最好的解决方案。但是,我仍然对为什么这不起作用感兴趣。这与定义在父视图中工作的点击识别器的代码相同。

func dismiss(_ sender:UITapGestureRecognizer) {
    nameFields.forEach { textFieldDidEndEditing([=12=]) }
}

override func viewDidAppear(_ animated: Bool) {
    for view in view.subviews where view is UIButton {
        let dismissTextField = UITapGestureRecognizer(target: self, action: #selector(dismiss(_:)))
        dismissTextField.numberOfTapsRequired = 1
        view.addGestureRecognizer(dismissTextField)
    }
}

您需要在 textFieldShouldReturn 方法中调用 resignFirstResponder 而不是调用 textFieldDidEndEditing.

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}

此外,在您的 TapGesture 方法中,只需使用 view 调用 endEditing(_:),而不是循环遍历文本字段数组。

func dismiss(_ sender:UITapGestureRecognizer) {
    self.view.endEditing(true)
}

Swift 5:下面这个解法其实简单多了

只需将带有文本字段的 ViewController 子类化为 UITextFieldDelegate,如下所示:

class CreateGroupViewController: UIViewController, UITextFieldDelegate {

然后,如果您将 UITextFields 命名为:nameTextField & occupationTextField,然后将以下委托添加到您的 viewDidLoad() 方法中:

self.nameTextField.delegate = self
self.occupationTextField.delegate = self

然后只需将通用函数添加到您的文件中即可:

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}

如果您这样做,那么对于您创建的每个 textField 引用插座,无论用户输入哪个 textField,它们都将在用户点击 return 按钮后隐藏键盘。对于您添加到视图中的每个文本字段,将另一个 self.nextTextField.delegate = self 行添加到您的 viewDidLoad.

请记住将 iPhone/iDevice 插入您的开发人员计算机进行测试,因为 XCode 的模拟器不会调出键盘(因为您通常使用全键盘进行测试)。或者,如果您已经通过 WiFi 设置了测试硬件 (iPhone),您也可以这样做。否则,您的用户将在 TestFlight 上 "testing"。