web-dev-qa-db-ja.com

モーダルViewControllerプレゼンテーションスタイルがUIModalPresentationFormSheetの場合、iPadキーボードは消えません。

注:

IOS 4.3の時点での解決策については、承認済みの回答(トップ投票ではありません)を参照してください。

これはquestionは、iPadキーボードで発見された動作に関するもので、Navigation Controllerのモーダルダイアログに表示された場合に却下を拒否します。

基本的に、Navigation Controllerに次の行を表示すると、次のようになります。

navigationController.modalPresentationStyle = UIModalPresentationFormSheet;

キーボードは閉じられません。この行をコメントアウトすると、キーボードはうまく機能しなくなります。

...

ユーザー名とパスワードの2つのtextFieldがあります。ユーザー名には[次へ]ボタンが、パスワードには[完了]ボタンがあります。モーダルナビゲーションコントローラーでこれを提示すると、キーボードは消えません。

作品

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

Navigation Controllerパーツを削除し、「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];
214
Kalle

モーダルで表示されるView Controllerでは、disablesAutomaticKeyboardDismissalをオーバーライドしてNOを返すだけです。

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}
115
Sebastian H

これは、Appleエンジニアによって「意図したとおりに動作する」と分類されています。私はしばらく前にこれについてバグを提出しました。その理由は、ユーザーがしばしばデータをモーダル形式で入力するため、「役に立つ」ようにし、通常はモーダルビュー内のさまざまな遷移によってキーボードの表示/非表示が繰り返される可能性のあるキーボードを表示しようとすることです。

編集: 応答はこちら 開発者フォーラムのAppleエンジニア:

UIModalPresentationFormSheetスタイルで表示された可能性はありますか?頻繁に出入りするアニメーションを避けるために、最初のレスポンダーがいない場合でもキーボードが画面上に残ることがあります。これはバグではありません。

これは多くの人々に問題を与えています(私自身も含めて)が、現時点ではそれを回避する方法はないようです。

UPDATE:

IOS 4.3以降では、NOを返すためにView Controllerに「-disablesAutomaticKeyboardDismissal」を実装できるようになりました。

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}

これにより問題が修正されます。

172
Mike Weller

UINavigationControllerでモーダルを表示する場合は注意してください。次に、View ControllerではなくNavigation Controllerで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を使用するファイルにカテゴリをインポートすることを忘れないでください。

149
Miha Hribar

これを解決するには、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];
51
azdev

UINavigationControllerで問題がある場合は、同様の質問に対する私の答えをここで参照してください: https://stackoverflow.com/a/10507689/321785

編集:私はこれがMiha Hribarのソリューションの改善であると考えています(決定が必要な場所で行われているため)、およびUIViewControllerのカテゴリに関するPascalのコメントとは対照的です

1
Chris Trahey

別のモーダル表示を切り替えると、キーボードが消えます。それはきれいではなく、下に動きませんが、あなたはそれを取り除くことができます。

修正があれば素晴らしいのですが、今のところはこれでうまくいきます。 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を呼び出すと、これらすべてのメソッドが呼び出されることに注意してください。私が言ったように、それはきれいではありませんが、動作します。

-アダム

1
Adam

このコードをviewWillDisappearに配置します。現在のコントローラーのメソッドは、これを修正する別の方法です。

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

また、イディオムをチェックするだけでユニバーサルアプリでこれを回避できます。iPadの場合は、キーボードを自動的にポップアップ表示せず、ユーザーが編集したいものをタップできるようにします。

最も良い解決策ではないかもしれませんが、それは非常に簡単であり、次の主要なiOSリリースで壊れる派手なハックを必要としません:)

1
Maciej Swic

完全な解決策ではないかもしれませんが、動作します
[self.view endEditing:YES];
モーダルを表示するためにボタンまたはジェスチャーが実装されている場所

0
Tanuj Jagoori

多分 NOを返さないが、YESを返す。だからそれは消えることができます。

そして、textFieldShouldEndEditingもYESを返しますか?

そしてなぜ[nextResponder becomeFirstResponder]を発射していますか?! ごめんなさい

また、すべての「編集可能」プロパティがFALSEに設定されているUITextViewがいくつかあります。

いずれにせよ、tagの値がsecondField.tag+1であるとは思わないでしょうか?もしそうなら、あなたはファーストレスポンダーを辞任するのではなく、ファーストレスポンダーになるように彼らに伝えています。たぶん、NSLog()をそのif構造に入れます。

0
mvds

これを見たことがあると思いますが、コントローラークラスがUITextFieldデリゲートとして適切に接続されていると確信していますよね?

0
Neal L
Swift 4.1:
extension UINavigationController {
   override open var disablesAutomaticKeyboardDismissal: Bool {
      return false
   }
}
0
fivewood

モーダルダイアログでdisablesAutomaticKeyboardDismissaldisablesAutomaticKeyboardDismissal関数を追加すると、UITextFieldに対して機能しませんでした。

オンスクリーンキーボードは消えません。

私の解決策は、ダイアログのすべてのテキスト入力コントロールをdisableにして、数秒後に関連するコントロールを再度有効にすることでした。

IOSがUITextFieldコントロールのどれも有効になっていないと認識すると、doesキーボードを削除します。

0
Mike Gledhill