如何使用多个UITextField关闭键盘

时间:2015-04-03 19:57:57

标签: ios iphone swift keyboard uitextfield

我在这里和iOS世界都是一个菜鸟。我在一个非常简单的待办事项列表iOS应用程序中解决特定情况下的键盘问题。

当用户点击当前文本字段或键盘本身之外的任何位置时,我希望键盘能够解除。到目前为止,当用户点击UITableView或我的应用程序上的大多数元素时,我让键盘解散得很好(感谢你们这里的堆栈溢出)。 HOWEVER 当用户点击另一个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()。所有这些都是假的。我也试过覆盖我的UIViewController的touchesBegan,在里面只调用self.view.endEditing(true)并调用它的super。这也行不通。

请帮忙。 :(

TIA!

更新: 你们真棒! :感谢你们,我现在就开始工作了。当我学习新框架时,有几个错误/搞砸了。所以这就是我的所作所为。

1)我没有正确设置UITextField委托。 错误:我在xcode中使用ctrl-draged textfield并将我的viewController链接为委托并认为应该可以解决。我仍然需要研究和理解更好的原因。 解决方案:我删除了ctrl-drag链接并在tableView:cellForRowAtIndexPath中显式调用myTextField.delegate = self。这样做了。谢谢@Sidewalker

2)错误:我混合了textFieldShouldBeginEditing等和@IBAction func EditingDidBegin。所以我自己进入了textFieldShouldBeginEditing接到调用的情况,但EditingDidBegin没有得到调用。 解决方案:一旦我明确地设置了delegate = self并坚持实现textField ...方法而不使用任何@IBAction用于textField,事情就会起作用。

5 个答案:

答案 0 :(得分:0)

键盘不会消失,因为它不希望这样。新的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;
}

答案 1 :(得分:0)

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

让您的课程遵守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
}

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

答案 2 :(得分:0)

首先将所有UITextField(您正在创建)委托设置为self并创建一个UITextField成员变量。现在实现“textFieldDidBeginEditing”委托方法,并将textfield分配给您的成员UITextField变量。如下所示

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

所以现在每当你想要关闭键盘时,都要调用“yourMemberVariable”对象上的dismiss方法。它应该工作!!

答案 3 :(得分:0)

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

第一个将UITapGestureRecognizer添加到整个UIViewController视图

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

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

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

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

答案 4 :(得分:0)

如何在viewController中执行此操作,对我有用

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