首页 文章

如果模态ViewController演示文稿样式为UIModalPresentationFormSheet,则iPad键盘不会被忽略

提问于
浏览
212

Note:

从iOS 4.3开始,请参阅已接受的答案(不是最受欢迎的答案) .

这个 question 是关于在iPad键盘中发现的行为,如果在带有导航控制器的模态对话框中显示,它将拒绝被解雇 .

基本上,如果我使用以下行显示导航控制器,如下所示:

navigationController.modalPresentationStyle = UIModalPresentationFormSheet;

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

...

我有两个textFields,用户名和密码; username有一个Next按钮,密码有一个Done按钮 . 如果我在模态导航控制器中显示它,键盘将不会消失 .

WORKS

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

DOES NOT WORK

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”作为模态视图控制器单独显示,则可以正常工作 . 导航控制器是问题吗?

WORKS

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

WORKS

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

13 回答

  • 1

    在以模态方式显示的视图控制器中,只需覆盖 disablesAutomaticKeyboardDismissal 以返回 NO

    - (BOOL)disablesAutomaticKeyboardDismissal {
        return NO;
    }
    
  • 114

    这被Apple工程师列为“按预定工作” . 我暂时为此提交了一个错误 . 他们的理由是用户经常会以模态形式输入数据,因此他们试图“有用”并保持键盘可见,通常模态视图中的各种过渡可能导致键盘重复显示/隐藏 .

    编辑:here is the response开发人员论坛上的Apple工程师:

    您的观点是否有机会呈现UIModalPresentationFormSheet风格?为了避免频繁的进出动画,即使没有第一响应者,键盘有时也会保持在屏幕上 . 这不是一个错误 .

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

    UPDATE:

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

    - (BOOL)disablesAutomaticKeyboardDismissal {
        return NO;
    }
    

    这解决了这个问题 .

  • 1

    如果要使用 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的文件中导入类别 .

  • 0

    我通过使用 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];
    
  • 0

    如果切换不同的模态显示,则可以使键盘消失 . 它并不漂亮而且没有动画效果,但你可以让它消失 .

    如果有一个修复它会很棒,但现在这个工作 . 您可以将其楔入 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中调用了所有这些方法,但要小心这一点 . 就像我说的那样,它并不漂亮,但确实有效 .

    -亚当

  • 0

    您也可以通过简单地检查成语来在通用应用程序中解决这个问题,如果它是iPad,则不要自动弹出键盘并让用户点击他们想要编辑的任何内容 .

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

  • 0

    对于那些遇到UINavigationController问题的人,请在此处查看我对类似问题的回答:https://stackoverflow.com/a/10507689/321785

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

  • 0

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

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

    我确定你看过这个,但是你确定你的控制器类已经正确连接为UITextField委托,对吧?

  • 1

    也许不回NO,但是YES . 所以它可以消失 .

    你还有 textFieldShouldEndEditing 返回YES吗?

    你为什么要解雇[nextResponder becomeFirstResponder]?!抱歉,我现在看到了

    我还有许多UITextViews都将其“可编辑”属性设置为FALSE .

    我们可以假设它们中没有一个具有 tagtag 值吗?如果是这样,你告诉他们成为第一响应者,而不是辞职第一响应者 . 如果结构可能会放一些NSLog() .

  • 172

    可能不是一个完美的解决方案,但有效
    [self.view endEditing:YES];
    从实现按钮或手势的任何地方到呈现模态

  • 1

    我发现 disablesAutomaticKeyboardDismissal 并且在模式对话框中添加 disablesAutomaticKeyboardDismissal 函数对我的 UITextField 不起作用 .

    屏幕键盘不会消失 .

    我的解决方案是禁用对话框中的所有文本输入控件,然后在几分之一秒后重新启用相关控件 .

    似乎当iOS看到没有启用任何 UITextField 控件时,它确实摆脱了键盘 .

  • 149
    Swift 4.1:
    extension UINavigationController {
       override open var disablesAutomaticKeyboardDismissal: Bool {
          return false
       }
    }
    

相关问题