Swift:无法让 UITextField 关闭键盘

Posted

技术标签:

【中文标题】Swift:无法让 UITextField 关闭键盘【英文标题】:Swift: Can't get UITextField to dismiss keyboard 【发布时间】:2017-03-06 05:32:58 【问题描述】:

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

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

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

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

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

1.试图关闭键盘。该方法的第一部分起作用,并且存储了值(即在完全调用该方法时)。光标在任何时候都不会从 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.尝试将点击识别器添加到完成按钮。我的代码中没有完成按钮的出口,只是出于懒惰,所以这可能是最好的解决方案。但是,我仍然对为什么这不起作用感兴趣。这与定义在父视图中工作的点击识别器的代码相同。

func dismiss(_ sender:UITapGestureRecognizer) 
    nameFields.forEach  textFieldDidEndEditing($0) 


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)
    

【问题讨论】:

【参考方案1】:

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

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

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

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

【讨论】:

天哪,我太笨了。我在正确的位置调用它,但我没有在任何东西上调用它。只需将 resignFirstResponder() 更改为 textField.resignFirstResponder() 即可解决所有问题。好吧,那并在代码中为完成按钮添加一个出口操作。谢谢!【参考方案2】:

Swift 5:下面的这个解决方案实际上要容易得多。

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

class CreateGroupViewController: UIViewController, UITextFieldDelegate 

然后,如果您将 UITextFields 命名为:nameTextField 和职业文本字段,则将以下委托添加到您的 viewDidLoad() 方法中:

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

然后简单地将通用函数添加到您的文件中:

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

如果您这样做,那么对于您创建的每个 textField 引用出口,无论用户键入哪个 textField,它们都会在用户点击返回按钮后隐藏键盘。对于您添加到视图中的每个 textField,将另一条 self.nextTextField.delegate = self 添加到您的 viewDidLoad 中。

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

【讨论】:

以上是关于Swift:无法让 UITextField 关闭键盘的主要内容,如果未能解决你的问题,请参考以下文章

Swift:UITextField 在第一次被点击时被立即关闭

Swift - 如何从 UIPickerView 生成数据的许多 UITextField 中读取数据 [关闭]

如何让 UITextField 只允许使用 Swift 3 的整数?

Swift——UITextField 没有显示键盘,我无法编辑它

Swift 如何让所有 uiTextfield 上的第一响应者辞职

显示用户在Swift中的UITextfield中键入的密码