如果模态ViewController的演示风格是UIModalPresentationFormSheet,iPad键盘不会解散

注意:

从iOS 4.3开始,查看接受的答案(不是顶级答案)。

这个问题是关于在iPad键盘上发现的行为,如果在导航控制器的模式对话框中显示,它拒绝被解雇。

基本上,如果我用下面的行显示导航控制器如下:

navigationController.modalPresentationStyle = UIModalPresentationFormSheet; 

键盘拒绝被解雇。 如果我注释掉这一行,键盘就会消失。

我有两个textFields,用户名和密码; 用户名有一个下一步button和密码有一个完成button。 如果我在模态导航控制器中显示这个键盘,键盘不会消失。

作品

 broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil]; [self.view addSubview:b.view]; 

不工作

 broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil]; UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:b]; navigationController.modalPresentationStyle = UIModalPresentationFormSheet; navigationController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; [self presentModalViewController:navigationController animated:YES]; [navigationController release]; [b release]; 

如果我删除了导航控制器部分,并将“b”作为一个模态视图控制器本身,它的工作原理。 导航控制器是问题吗?

作品

 broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil]; b.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; [self presentModalViewController:b animated:YES]; [b release]; 

作品

 broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil]; UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:b]; [self presentModalViewController:navigationController animated:YES]; [navigationController release]; [b release]; 

在模态提交的viewController只是覆盖disablesAutomaticKeyboardDismissal总是返回NO

 - (BOOL)disablesAutomaticKeyboardDismissal { return NO; } 

这已被苹果工程师分类为“按预期工作”。 我早就提出了一个错误。 他们的推理是,用户经常会以模态formsinput数据,所以他们试图“有帮助”,并保持键盘可见,通常在模态视图内的各种转换可能导致键盘反复显示/隐藏。

编辑: 这里是苹果工程师在开发者论坛上的回应 :

你的观点是由UIModalPresentationFormSheet风格提供的吗? 为避免频繁进出的animation,即使没有第一响应者,键盘有时仍保持在屏幕上。 这不是一个错误。

这给人们带来了很多问题(包括我自己),但目前似乎还没有办法解决这个问题。

更新:

在iOS 4.3及更高版本中,您现在可以在视图控制器上实现`-disablesAutomaticKeyboardDismissal'来返回NO:

 - (BOOL)disablesAutomaticKeyboardDismissal { return NO; } 

这解决了这个问题。

如果使用UINavigationController显示模式,请小心。 然后您必须在导航控制器上设置disablesAutomaticKeyboardDismissal ,而不是在视图控制器上。 你可以很容易地做到这一点与类别。

文件:UINavigationController + KeyboardDismiss.h

 #import <Foundation/Foundation.h> @interface UINavigationController (KeyboardDismiss) - (BOOL)disablesAutomaticKeyboardDismissal; @end 

文件:UINavigationController + KeyboardDismiss.m

 #import "UINavigationController+KeyboardDismiss.h" @implementation UINavigationController(KeyboardDismiss) - (BOOL)disablesAutomaticKeyboardDismissal { return NO; } @end 

不要忘记在使用UINavigationController的文件中导入类别。

我通过使用UIModalPresentationPageSheet演示样式解决了此问题,并在呈现它之后立即调整其大小。 像这样:

 viewController.modalPresentationStyle = UIModalPresentationPageSheet; viewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; [self presentModalViewController:viewController animated:YES]; viewController.view.superview.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; viewController.view.superview.frame = CGRectMake( viewController.view.superview.frame.origin.x, viewController.view.superview.frame.origin.y, 540.0f, 529.0f ); viewController.view.superview.center = self.view.center; [viewController release]; 

如果你切换不同的模式显示,你可以让键盘消失。 这不是很漂亮,它不会animation,但你可以让它消失。

如果有一个修复,这将是很好的,但现在这个工作。 你可以把它放在UIViewController一个类中,当你想要键盘消失的时候调用它:

 @interface _TempUIVC : UIViewController @end @implementation _TempUIVC - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } @end @implementation UIViewController (Helpers) - (void)_dismissModalViewController { [self dismissModalViewControllerAnimated:NO]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidHideNotification object:nil]; [self release]; } - (void)forceKeyboardDismissUsingModalToggle:(BOOL)animated { [self retain]; _TempUIVC *tuivc = [[_TempUIVC alloc] init]; tuivc.modalPresentationStyle = UIModalPresentationCurrentContext; [self presentModalViewController:tuivc animated:animated]; if (animated) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_dismissModalViewController) name:UIKeyboardDidHideNotification object:nil]; } else [self _dismissModalViewController]; [tuivc release]; } @end 

当你viewDidAppear / viewDidDisappear和所有这些方法被调用时要小心。 就像我说的那样,这不太好,但确实有效。

-亚当

您也可以在通用应用程序中解决这个问题,只需检查成语,如果是iPad,则不要自动popup键盘,让用户点击任何他们想要编辑的内容。

可能不是最好的解决scheme,但它非常简单,不需要任何花哨的黑客,将打破下一个主要的iOS版本:)

对于那些有UINavigationController的麻烦,看到我的答案在这里类似的问题: https : //stackoverflow.com/a/10507689/321785

编辑:我认为这是对Miha Hribar解决scheme的改进(因为决定发生在它应该在的地方),而不是Pascal关于UIViewController类别的评论

把这个代码放在viewWillDisappear中:当前控制器的方法是解决这个问题的另一种方法:

 Class UIKeyboardImpl = NSClassFromString(@"UIKeyboardImpl"); id activeInstance = [UIKeyboardImpl performSelector:@selector(activeInstance)]; [activeInstance performSelector:@selector(dismissKeyboard)]; 

我相信你已经看过这个,但是你确定你的控制器类被正确地连接成了UITextField委托,对吗?

也许不要回不,但是。 所以它可以消失。

你有一个textFieldShouldEndEditing返回YES以及?

为什么要发射[nextResponder becomeFirstResponder] 对不起,我现在看到

我也有一些UITextView的所有“可编辑”属性设置为FALSE。

我们可以假设他们中的任何一个都没有tagsecondField.tag+1吗? 如果是这样,你告诉他们成为第一响应者,而不是第一响应者辞职。 也许把一些NSLog()中,如果结构。

可能不是一个完美的解决scheme,但工程
[self.view endEditing:YES];
无论你的button或手势实施到现在的模式

我发现disablesAutomaticKeyboardDismissal和添加一个disablesAutomaticKeyboardDismissalfunction不适用于我的UITextField在模式对话框中。

屏幕键盘不会消失。

我的解决scheme是禁用我的对话框中的所有文本input控件,然后在几分之一秒后重新启用相关的控件。

看起来好像当iOS看到没有UITextField控件被启用,那么它确实摆脱了键盘。