ios 如果模态 ViewController 呈现样式是 UIModalPresentationFormSheet,iPad 键盘不会关闭

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3372333/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:29:44  来源:igfitidea点击:

iPad keyboard will not dismiss if modal ViewController presentation style is UIModalPresentationFormSheet

iosiphoneobjective-cuitextfieldfirst-responder

提问by Kalle

Note:

笔记:

See accepted answer (not top voted one) for solution as of iOS 4.3.

有关 iOS 4.3 的解决方案,请参阅已接受的答案(不是最高投票的答案)。

This questionis about a behavior discovered in the iPad keyboard, where it refuses to be dismissed if shown in a modal dialog with a navigation controller.

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

Basically, if I present the navigation controller with the following line as below:

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

navigationController.modalPresentationStyle = UIModalPresentationFormSheet;

The keyboard refuses to be dismissed. If I comment out this line, the keyboard goes away fine.

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

...

...

I've got two textFields, username and password; username has a Next button and password has a Done button. The keyboard won't go away if I present this in a modal navigation controller.

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

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];

If I remove the navigation controller part and present 'b' as a modal view controller by itself, it works. Is the navigation controller the problem?

如果我删除导航控制器部分并将 '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];

采纳答案by Sebastian H

In the view controller that is presented modally, just override disablesAutomaticKeyboardDismissalto return NO:

在以模态呈现的视图控制器中,只需覆盖disablesAutomaticKeyboardDismissal即可返回NO

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}

回答by Mike Weller

This has been classified as "works as intended" by Apple engineers. I filed a bug for this a while back. Their reasoning is that the user is often going to be entering data in a modal form so they are trying to be "helpful" and keep the keyboard visible where ordinarily various transitions within the modal view can cause the keyboard to show/hide repeatedly.

这已被 Apple 工程师归类为“按预期工作”。不久前我为此提交了一个错误。他们的理由是用户通常会以模态形式输入数据,因此他们试图“有用”并保持键盘可见,而模态视图中的各种转换通常会导致键盘重复显示/隐藏。

edit: here is the responseof an Apple engineer on the developer forums:

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

Was your view by any chance presented with the UIModalPresentationFormSheet style? To avoid frequent in-and-out animations, the keyboard will sometimes remain on-screen even when there is no first responder. This is not a bug.

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

This is giving a lot of people problems (myself included) but at the moment there doesn't seem to be a way to work around it.

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

UPDATE:

更新:

In iOS 4.3 and later, you can now implement `-disablesAutomaticKeyboardDismissal' on your view controller to return NO:

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

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}

This fixes the issue.

这解决了这个问题。

回答by Miha Hribar

Be careful if you are displaying the modal with a UINavigationController. You then have to set the disablesAutomaticKeyboardDismissalon the navigation controller and not on the view controller. You can easily do this with categories.

如果您使用UINavigationController. 然后,您必须disablesAutomaticKeyboardDismissal在导航控制器上而不是在视图控制器上设置 。您可以使用类别轻松地做到这一点。

File: UINavigationController+KeyboardDismiss.h

文件:UINavigationController+KeyboardDismiss.h

#import <Foundation/Foundation.h>

@interface UINavigationController (KeyboardDismiss)

- (BOOL)disablesAutomaticKeyboardDismissal;

@end

File: UINavigationController+KeyboardDismiss.m

文件:UINavigationController+KeyboardDismiss.m

#import "UINavigationController+KeyboardDismiss.h"

@implementation UINavigationController(KeyboardDismiss)

- (BOOL)disablesAutomaticKeyboardDismissal
{
    return NO;
}

@end

Do not forget to import the category in the file where you use the UINavigationController.

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

回答by azdev

I solved this by using the UIModalPresentationPageSheetpresentation style and resizing it immediately after I present it. Like so:

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

回答by Maciej Swic

You could also work around this in a universal app by simply checking the idiom and if it's an iPad, don't pop up the keyboard automatically at all and let the user tap whatever they want to edit.

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

May not be the nicest solution but it's very straightforward and doesn't need any fancy hacks that will break with the next major iOS release :)

可能不是最好的解决方案,但它非常简单,不需要任何会在下一个主要 iOS 版本中崩溃的花哨的 hack :)

回答by Adam

If you toggle a different modal display you can get the keyboard to disappear. It's not pretty and it doesn't animate down, but you can get it to go away.

如果您切换不同的模式显示,您可以让键盘消失。它不漂亮,也没有动画,但你可以让它消失。

It'd be great if there was a fix, but for now this works. You can wedge it in a category on UIViewControllerand call it when you want the keyboard gone:

如果有修复,那就太好了,但现在这有效。你可以把它放在一个类别中,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

Be careful with this though as you viewDidAppear / viewDidDisappear and all those methods get called. Like I said, it's not pretty, but does work.

但是当你 viewDidAppear / viewDidDisappear 和所有这些方法被调用时要小心。就像我说的,它不漂亮,但确实有效。

-Adam

-亚当

回答by Story

Put this code in your viewWillDisappear: method of current controller is another way to fix this:

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

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

回答by Mike Gledhill

I found that disablesAutomaticKeyboardDismissaland adding a disablesAutomaticKeyboardDismissalfunction didn't work for my UITextFieldin a modal dialog.

我发现在模态对话框中disablesAutomaticKeyboardDismissal添加一个disablesAutomaticKeyboardDismissal函数对我不起作用UITextField

The onscreen keyboard just wouldn't go away.

屏幕键盘不会消失。

My solution was to disableall text-input controls in my dialog, then re-enable the relevant ones a fraction of a second later.

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

It seems as though when iOS sees that none of the UITextFieldcontrols are enabled, then it doesget rid of the keyboard.

似乎当 iOS 发现没有UITextField启用任何控件时,它确实摆脱了键盘。

回答by fivewood

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

回答by Tanuj Jagoori

may be not a perfect solution ,but works
[self.view endEditing:YES];
from wherever your button or gesture is implemented to present modal

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