模态对话框无法关闭键盘

41

我遇到了一个问题,当在UIModalPresentationFormSheet中离开UITextFieldUITextView时,键盘没有被关闭。此外,我创建了一个大按钮作为视图的背景,以便如果用户在字段外面点击它就会被触发。我在常规视图控制器中使用相同的代码,它按预期工作。但在模态视图控制器中它不起作用。任何建议将不胜感激。

- (BOOL)textFieldShouldReturn:(id)sender {  
 [titleTextField resignFirstResponder];
 return YES;
}

- (BOOL)textViewShouldReturn:(id)sender {  
 [synopsisTextView resignFirstResponder];
 return YES;
}

- (IBAction)textFieldDoneEditing:(id)sender {  
 [sender resignFirstResponder];
} 

- (IBAction)textViewDoneEditing:(id)sender {  
 [sender resignFirstResponder];
} 

- (IBAction)backgroundClick:(id)sender {  
 [titleTextField resignFirstResponder];
 [synopsisTextView resignFirstResponder];
}

不知道你是否解决了这个问题,但我遇到了类似的问题:https://dev59.com/sXA75IYBdhLWcg3wS3BA - Kalle
7个回答

119

通过覆盖重写 disablesAutomaticKeyboardDismissal 方法并返回 NO 可以解决类似的问题。你应该将以下代码放入你的视图控制器中,从中启动键盘:

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}

此外,如果你想获得详细的解释,请查看 SO 上的这个问题。


可以了,谢谢!这真的很棘手。我怎么可能自己想出来呢?唉!! - Hlung
我认为你应该将代码放到作为模态视图控制器呈现的视图控制器中。如果你正在以模态方式呈现UINavigationController(带有堆栈上的视图控制器),那么你应该对其进行子类化并在其中覆盖该方法。 - manicaesar
4
我无数次尝试在ViewController中使用它都失败了,但我继续添加了一个带有它的NavigationController子类,成功了! - Josh Kahane
2
如果你的模态视图控制器位于UINavigationController中,可以尝试@ctrahey提出的答案,通过在UINavigationController上创建一个类别,在其topViewController上调用disablesAutomaticKeyboardDismissal。 - joelsand
非常感谢您! - crojassoto
显示剩余2条评论

51

对于那些在使用UINavigationController时遇到困难的人,我认为有一个比在UIViewController上创建类别更好的解决方案。我们应该改变UINavigationController的行为,使其询问其topViewController(在我看来,所有ViewController容器都应该这样处理)。

@implementation UINavigationController (DelegateAutomaticDismissKeyboard)
- (BOOL)disablesAutomaticKeyboardDismissal {
    return [self.topViewController disablesAutomaticKeyboardDismissal];
}

好的建议,帮我省了很多麻烦! - jjxtra
2
我们真的应该在类别中覆盖方法吗?感觉不太对。 - Edward Huynh
为了帮助像我这样的新手,只需子类化UINavigationController并添加一个方法-(BOOL)disablesAutomaticKeyboardDismissal {return [self.topViewController disablesAutomaticKeyboardDismissal];} - Joshua Dance
这个应该作为子类来完成。我非常喜欢分类,但覆盖方法是它们绝对不应该用于的事情!https://dev59.com/WW435IYBdhLWcg3wrSPN - Rembrandt Q. Einstein
@RembrandtQ.Einstein 这是一个很好的观点,但有时候过于小心也是不必要的。使用 Categories 时需要注意的是,在覆盖已经实现的方法时(即不仅仅是其祖先类中的方法),需要谨慎。现在,确实,在 任何 Apple 提供的类上这样做都存在风险,因为您无法保证未来 SDK 的更改。然而,使用分类而不是子类的价值非常显著:现在,您甚至可以将此行为用于您没有控制实例化的导航控制器。这是一个非常重要的问题。 - Chris Trahey
@ctrahey 是的,这是出于谨慎的考虑,但使用类别覆盖方法的特定危险是针对苹果框架类的。如果您想要覆盖或扩展一个没有源代码的类的方法,正确的方法是方法交换。 - Rembrandt Q. Einstein

3

如果您使用“表单表格”样式呈现模态视图,则苹果显然不会关闭键盘,因为他们认为在用户需要大量编辑的地方(即“表单”),键盘会跳进跳出。解决方法是更改演示样式或接受这种情况。


是的,我正在使用UIModalPresentationFormSheet。谢谢你提供的信息。 - DenVog
非常让人困扰的是,为了使ModalVC平稳地淡出,您需要先将键盘动画化。https://dev59.com/uk3Sa4cB1Zd3GeqPz_0T - Nick Cartwright
参见 @ctrahey 上面的回答,将一个类别添加到 UINavigationController。这为我解决了问题。 - Chris Ladd

1
如果您实现了UITextFieldDelegate协议并进行文本验证,可能会无意中导致此行为。如果您的验证代码在textFieldShouldEndEditing返回false时文本无效,则该字段无法放弃其firstResponder状态,并且键盘将保留在下一个视图中。
更多详细信息请参见UITextField的键盘无法消失。不,真的

0

我通过调整 UIModalPresentationPageSheet 的大小来解决了这个问题。请查看我的答案这里


0

disablesAutomaticKeyboardDismissal 在 iOS 7 上对我不起作用。

但是... 我通过简单地在屏幕上禁用 UITextFields 来解决了这个问题。

我的解决方案在 这里 描述。

这个解决方法甚至适用于模态 UIViewController

是的... 它也让我感到惊讶!!


0

我也遇到了同样的问题,尝试了各种方法都没用,后来开始思考并得出了一些结果。

但这个答案适用于那些想在点击文本框后关闭键盘并打开弹出窗口的人。

所以你需要调用文本框代理。

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    if textField == self.myTxtFieldName{
        self.view.endEditing(true) // keyboard hide code
        // here you can call your model or pop up code and keyboard will dismiss and your pop up open 
        return false 
    } 
     return true
} 

如果这对你不起作用,很抱歉。 如果有其他答案,请编辑它。 谢谢。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接