web-dev-qa-db-ja.com

iOS 8.3 for iPadでUIAlertViewが閉じられた後にキーボードがポップアップする

最新のiOS 8.3リリースでは、アプリの動作がおかしくなっています。

テキストフィールドの編集が終了したら、ユーザーはUIAlertViewを表示する閉じるボタンをクリックできます。ユーザーがalertviewでdiscardをクリックすると、alertviewと現在のビューが閉じられます。しかし、どういうわけか、ビューが消えた後にキーボードが表示され、ユーザーにとって非常に迷惑です。

デバッグ後、ビューを閉じる前にユーザーがアクセスした最後のテキストフィールドにキーボードが表示されているようです。多くの場所で現在のビューのendEditingにさまざまな方法を試しました(UIAlertViewのボタンをクリックした後、UIAlertViewを表示する前に、別のUI要素にフォーカスを設定しました。ビューの)。問題は解決しませんでした。

しかし、この特定の問題については、それが一般的な問題なのか、修正が必要なものなのかわかりません。 iOS 8.3より前のすべては完全に機能します。

UIAlertViewはiOS 8で廃止されることを理解しています。UIAlertControllerへの移行を開始します。しかし、回避策があれば、ぜひ聞いてみてください。

コードスニペットを次に示します。

- (IBAction)closeTapped:(UIButton *)sender
{
    // try to resign first responder
    // [self.tfName resignFirstResponder];
    // [self.tfPosition resignFirstResponder];
    [self.view endEditing:YES];

    if(self.orderDetails.isOpen && self.orderItemChanged)
    {
        UIAlertView* saveAlert = [[UIAlertView alloc] initWithTitle:@"Unsaved Changes"
                                                            message:@"Your changes have not been saved. Discard changes?"
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:@"Save", @"Discard", nil];
        [saveAlert show];
    }
    else
    {
        [self close];
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    switch(buttonIndex)
    {
        case 1: // Save
        {
            [self save];
            break;
        }
        case 2: // Discard
        {
            [self close];
            break;
        }
    }
}

- (void)close
{   
    [self.delegate dismissEditOrderItemVC];
}
34
Helen

展開ターゲットがiOS 8以降の場合、UIAlertControllerを試してください。

UIAlertViewの簡単な修正:テキストフィールドまたはテキストビューが最初のレスポンダーを辞任したときにアラートビューを表示する呼び出しを遅らせます。

[self performSelector:@selector(showAlertView) withObject:nil afterDelay:0.6];
14
Yiming Tang

誰かがこれに苦労しているなら、これが役立つことを願っています:

if (NSClassFromString(@"UIAlertController")) {
    UIAlertController* alert = ...
}
else {
    UIAlertView* alert = ...
}
3
puzzler

iOS 8.3のアラートを変更する必要があります

最初にこれをあなたの見解に入れてください

#define IS_IOS8 [[UIDevice currentDevice].systemVersion floatValue] >= 8.0

それから

if (IS_IOS8) {

        UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Unsaved Changes" message:@"Your changes have not been saved. Discard changes?" preferredStyle:UIAlertControllerStyleAlert];

        UIAlertAction *saveAction = [UIAlertAction
                                    actionWithTitle:@"Save"
                                    style:UIAlertActionStyleCancel
                                    handler:^(UIAlertAction *action)
                                    {
                                        [self save];
                                    }];

        UIAlertAction *cancelAction = [UIAlertAction
                                   actionWithTitle:@"Cancel"
                                   style:UIAlertActionStyleCancel
                                   handler:^(UIAlertAction *action)
                                   {
                                       [alertVC dismissViewControllerAnimated:YES completion:nil];
                                   }];


        UIAlertAction *discardAction = [UIAlertAction
                                   actionWithTitle:@"Discard"
                                   style:UIAlertActionStyleCancel
                                   handler:^(UIAlertAction *action)
                                   {
                                       [alertVC dismissViewControllerAnimated:YES completion:nil];
                                   }];



        [alertVC addAction:saveAction];
        [alertVC addAction:cancelAction];
        [alertVC addAction:discardAction];
        [self.view.window.rootViewController presentViewController:alertVC animated:YES completion:nil];

同じ問題で私を助けてくれるので、これはあなたを助けます。上記のコードはiOS 7と8の両方と互換性があります

2
Nik

私も、UIAlertControllerを閉じた後にキーボードが(最後に使用したtextViewにカーソルを置いて)ポップアップしました。これは非常に簡単な修正です。

UIAlertControllerを作成して表示する直前に、

[_activeTextView resignFirstResponder]を使用します。キーボードが再表示されます。 [self.view endEditing:YES]を使用します。キーボードは再表示されません。

これがあなたのお役に立てば幸いです。

2
Steve W.

テキストフィールドが最初のレスポンダーである場合、アラートが消えるとキーボードが自動的にポップアップします。最初のレスポンダーが適切に解雇されることを確認します:

[textField resignFirstResponder]

要確認:テーブルまたはスクロールビューでは、レスポンダーを適切に閉じるためにフィールドが画面上に表示されている必要がある場合があります。

アクティブな最初のレスポンダーがいない場合、アラートが消えてもキーボードは表示されません。

この質問の特定のケースでは、デリゲートメソッドを設定して「完了」ボタンをリッスンし、デリゲートコールバックで最初のレスポンダーを辞任することをお勧めします。

または、編集を開始するときに、現在アクティブなテキストフィールドへの参照を保存し、「clickedButtonAtIndex」メソッドでアクティブなテキストフィールドがまだアクティブである場合、それを辞任することができます。

1
Lytic

以下のコードを使用してみてください。 iOS 8以前のバージョンでは正常に動作します

if (IS_OS_8_OR_LATER) {
        UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];

        UIAlertAction *cancelAction = [UIAlertAction
                                     actionWithTitle:@"OK"
                                     style:UIAlertActionStyleCancel
                                     handler:^(UIAlertAction *action)
                                     {

                                     }];
        [alertVC addAction:cancelAction];

        [[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] presentViewController:alertVC animated:YES completion:^{

        }];
    }
    else{
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
        [alert show];
    }

}

1
amitshinik

TextFieldキーボードとalertViewsの奇妙な振る舞いにも気づきました... disableKeyboardというboolを作成し、次のように使用するかもしれません。

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {

    if (disableKeyBoard) {

        disableKeyboard = NO;
        return NO;

    } else {

        return YES;

    }

}

- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {

    disableKeyboard = YES;

}

これは単なる回避策であり、コアの問題に対処するものではありません。このメソッドを機能させるには、ヘッダーにalertViewおよびtextFieldデリゲートメソッドを設定する必要があります。

0
Mike E