带文本字段的UIAlertController:如何解除键盘的工作原理?

时间:2018-06-11 14:56:20

标签: ios uialertcontroller uitextfielddelegate resignfirstresponder

在我的UIViewController子类中,我使用UIAlertController创建了UITextField

class MyViewController: UIViewController {
...

     let alertController = UIAlertController(title: "a title", message: "", preferredStyle: .alert)
     let okAction = UIAlertAction(title: "OK!", style: .default) { alert in
          print("OK!!")
     }
     alertController.addTextField { (textField) in
     textField.placeholder = "a placeholder"
     textField.delegate = self
     }
     alertController.addAction(okAction)
     self.present(alertController, animated: true, completion: nil)

...

}

extension MyViewController: UITextFieldDelegate {
      func textFieldShouldReturn(_ textField: UITextField) -> Bool {
          return true
      }
}

现在,当显示警告并点击键盘下一个/完成按钮时,键盘和警报将被解除,并且 OK!将被打印。

在我的textFieldShouldReturn方法中,既没有textField.resignFirstResponder()也没有警告解除命令,那么键盘和警报如何被解除? Apple如何实现这种行为?有textField两位代表吗?

3 个答案:

答案 0 :(得分:1)

实际上,你并没有足够强烈地提出这个问题。您可以删除您的扩展程序和行textField.delegate = self,当用户点击返回时,警报仍然会被忽略。

该行为对于警报是自动的。除非您禁用了“关闭”按钮,否则当用户在虚拟键盘中点击“返回”时,默认情况下会为您点按。

至于实际机制,它是一个editingDidEndOnExit控件事件。这样您就可以自由地设置代理而不会搞砸了。

答案 1 :(得分:1)

As matt already mentioned,对于包括textField的警报而言,这种行为是正常的。 一旦您按下键盘上的回车键,它就会触发.editingDidEndOnExit,这将关闭键盘和警报。

您可以通过仅删除textField上的目标来防止这种行为:

  textField.removeTarget(nil, action: nil, for: .editingDidEndOnExit)

一旦您点击键盘上的回车键,它将不再消除警报。

答案 2 :(得分:0)

我想了解Apple UIAlertController行为,以便在我实施的警报自定义控制器中添加相同的行为。有了@ matt的回答帮助,我想我已经弄明白了UIAlertController的工作原理。在我的代码段下面 connect 所有提醒的文本字段:

guard let last = textFields.last else {
    return
}
for i in 0 ..< textFields.count - 1 {
    textFields[i].returnKeyType = .next
    textFields[i].addTarget(textFields[i+1], action: #selector(UIResponder.becomeFirstResponder), for: .editingDidEndOnExit)
}
last.returnKeyType = .done
last.addTarget(last, action: #selector(UIResponder.resignFirstResponder), for: .editingDidEndOnExit)

这样当我点击键盘下一个/完成按钮并且最后一个文本字段是第一个响应者时,键盘被解除;否则下一个文本字段成为第一个响应者。

post也有帮助。