如何关闭具有多个 UITextField 的键盘

How to dismiss keyboard with multiple UITextField

我是这里和 iOS 世界的菜鸟。在我非常简单的待办事项列表 iOS 应用程序中的特定情况下,我无法关闭键盘。

我希望当用户点击当前文本字段以外的任何地方或键盘本身时,键盘会消失。到目前为止,当用户点击 UITableView 或我的应用程序上的大多数元素时,我的键盘消失得很好(感谢堆栈溢出中的你们)。 但是当用户点击另一个 UITextField 时,键盘不会消失

仅供参考,这是我目前研究过但尚未解决此问题的现有线程列表。 1) How to dismiss keyboard iOS programmatically 2) Resigning First Responder for multiple UITextFields 3) Dismissing the First Responder/Keyboard with multiple Textfields 4)(至少还有一些,但我忘记了 :( )

这是我目前所做的:

(in viewDidLoad())
// Add 'tap' gesture to dismiss keyboard when done adding/editing to-do item
var tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "tapOutside:")
tap.cancelsTouchesInView = true
self.view.addGestureRecognizer(tap)

func tapOutside(tapOutside: UIGestureRecognizer) {
   // Dismiss keyboard
   self.view.endEditing(true)
}

@IBAction func EditingDidBegin(sender: UITextField) {
   // Highlight the text field which user is editing
   self.highlightTextField(sender, highlight: true)
}

@IBAction func EditingDidEnd(sender: UITextField) {
   // Undo text field highlight
   self.highlightTextField(sender, highlight: false)

   self.view.endEditing(true)  // try this option and not working
   self.setEditing(false, animated: true)   // try this option and not working
   sender.resignFirstResponder()   // try this option and not working
   UIApplication.sharedApplication().becomeFirstResponder()   // try this option and not working

   ... // below is my code to update the todo item
}

我还尝试打印出我的所有 subviews.isFirstResponder() 视图。所有这些 return 都是错误的。我还尝试覆盖我的 UIViewController 的 touchesBegan,在它内部只调用 self.view.endEditing(true) 并调用它的 super。这也行不通。

请帮忙。 :(

TIA!

更新: 你们真棒! :D 多亏了你们,我现在可以正常工作了。在学习新框架时出现了一些错误/混乱。这就是我所做的。

1) 我没有正确设置 UITextField 委托。 错误:我在 xcode 和 link 我的 viewController 中按住 textfield 作为代表,我认为这应该可行。我仍然需要研究并更好地理解原因。 解决方案:我删除了 ctrl-drag link 并在 tableView:cellForRowAtIndexPath 中显式调用 myTextField.delegate = self。就是这样。谢谢@Sidewalker

2) 错误:我混合了 textFieldShouldBeginEditing 等和@IBAction func EditingDidBegin。所以我陷入了 textFieldShouldBeginEditing 接到电话但 EditingDidBegin 没有接到电话的情况。 解决方案:一旦我显式设置了 delegate = self 并坚持实现 textField... 方法并且不对 textField 使用任何 @IBAction,一切正常。

好吧,键盘不会消失,因为它预计不会消失。新的 UITextField 刚刚成为第一响应者,而另一个则辞职了。如果您不希望 textField 成为第一响应者(如果另一个已经成为第一响应者),则必须在它有机会之前将其切断。我会尝试实现 textFieldShouldBeginEditing 并弄清楚那里的逻辑。

我不喜欢它的外观,但它应该按照这些思路做一些事情。

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
    for subView in self.view.subviews{
        if(subView.isKindOfClass(UITextField)){
            if(subView.isFirstResponder()){
                subView.resignFirstResponder();
                return false;
            }
        }
    }
    return true;
}

这是一个选项...我们将添加一个布尔标志,以确定当对另一个文本字段的编辑尝试开始时我们是否在文本字段中

让你的 class 遵守 UITextFieldDelegate

class MyClass: UIViewController, UITextFieldDelegate

不要忘记设置委托,我们也会添加标志

myTextField.delegate = self
var inField = false

实施"textFieldShouldBeginEditing"和"textFieldDidBeginEditing"

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
    if inField {
        inField = false
        return false
    } 
    return true
}

func textFieldDidBeginEditing(textField: UITextField) {
    inField = true
}

我更喜欢跟踪这样的事情而不是识别子视图,因为它允许在其他地方使用标志并减少代码复杂性。

首先将所有 UITextField(您正在创建的)委托设置为 self 并创建一个 UITextField 成员变量。现在实施 "textFieldDidBeginEditing" 委托方法并将文本字段分配给您的成员 UITextField 变量。如下所示

func textFieldDidBeginEditing(textField: UITextField) {
    yourMemberVariable = textField;
}

所以现在每当你想关闭键盘时调用 "yourMemberVariable" 对象上的 dismiss 方法。它应该有效!!

我通常做的是实现这两个方法:

第一个给整个UIViewController视图添加一个UITapGestureRecognizer

func hideKeyboard() {
    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
    view.addGestureRecognizer(tap)
}

每当用户触摸 UIViewController 视图的任何地方时,第二个就会被调用

func dismissKeyboard() {
    self.view.resignFirstResponder()
}

我将第一个添加到 UIViewController 的 viewDidLoad 方法中。或者更好的是,如果你想在所有应用程序上使用它,只需将它作为你的 UIViewController 的扩展。

在 viewController 中这样做怎么样,对我有用

func dismissKeyboard() {
    //All the textFields in the form
    let textFields = [textField1, textField2, textField3, textField4, textField5]
    let firstResponder = textFields.first(where: {[=10=].isFirstResponder ?? false })
    firstResponder?.resignFirstResponder()
}