web-dev-qa-db-fra.com

Le clavier apparaît après le rejet d'UIAlertView sur iOS 8.3 pour iPad

Avec la dernière version iOS 8.3, notre application commence à avoir un comportement étrange.

Après avoir terminé l'édition du champ de texte, l'utilisateur peut cliquer sur le bouton de fermeture qui fait apparaître un UIAlertView. Lorsque l'utilisateur clique sur ignorer dans la vue d'alerte, la vue d'alerte et la vue actuelle sont ignorées. Mais d'une manière ou d'une autre, le clavier apparaît après la disparition de la vue, ce qui est assez ennuyeux pour les utilisateurs.

Après quelques débogages, il semble que le clavier s'affiche pour le dernier champ de texte auquel l'utilisateur a accédé avant de fermer la vue. J'ai essayé plusieurs façons de endEditing pour la vue actuelle à plusieurs endroits (avant d'afficher UIAlertView, après avoir cliqué sur un bouton dans le UIAlertView; j'ai même mis le focus sur un autre élément de l'interface utilisateur de la vue). Cela n'a pas résolu le problème.

Mais pour ce problème particulier, je ne sais pas s'il s'agit d'un problème courant ou de quelque chose que nous devons résoudre. Tout fonctionne parfaitement avant iOS 8.3.

Nous comprenons que UIAlertView est déconseillé pour iOS 8. Nous commençons à migrer vers UIAlertController. Mais s'il y a une solution, nous aimerions entendre.

Voici un extrait de code.

- (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

Si votre cible de déploiement est iOS 8+, essayez UIAlertController.

Voici une solution rapide pour UIAlertView: retardez l'appel de l'affichage de l'alerte lorsque votre champ de texte ou votre vue de texte démissionne en premier.

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

Si quelqu'un lutte avec cela, j'espère que cela vous aidera:

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

vous devez changer d'alerte pour ios 8.3

mettez d'abord cela à votre avis

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

ensuite

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

cela vous aidera car il m'aide dans le même problème. le code ci-dessus est compatible avec ios 7 et 8

2
Nik

Moi aussi, j'ai fait apparaître un clavier (avec le curseur dans le dernier textView utilisé) après avoir fermé un UIAlertController et voici une solution très simple:

Immédiatement avant la construction et la présentation de l'UIAlertController,

Utilisation de [_activeTextView resignFirstResponder]; le clavier réapparaîtra. Utilisation de [self.view endEditing: YES]; le clavier NE réapparaîtra PAS.

J'espère que ceci vous aide.

2
Steve W.

Si un champ de texte est le premier répondeur, il affichera automatiquement le clavier lorsque l'alerte est rejetée. Assurez-vous que le premier répondant est correctement renvoyé avec:

[textField resignFirstResponder]

Rappelez-vous: dans une vue en tableau ou en défilement, le champ doit parfois être visible à l'écran pour renvoyer correctement le répondeur.

S'il n'y a pas de premiers intervenants actifs, le clavier ne devrait pas apparaître lorsque l'alerte est rejetée.

Pour le cas particulier de cette question, je recommanderais de définir une méthode déléguée pour écouter le bouton "terminé" et de démissionner du premier répondeur dans le rappel du délégué.

Alternativement, au début de l'édition, vous pouvez stocker une référence au champ de texte actuellement actif, puis dans votre méthode "clickedButtonAtIndex", vous pouvez résigner le champ de texte actif s'il est toujours actif.

1
Lytic

Essayez d'utiliser le code ci-dessous. Cela fonctionne bien pour iOS 8 et versions antérieures

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

J'ai remarqué un comportement étrange avec les claviers textField et alertViews ... Peut-être faites un bool appelé disableKeyboard et utilisez-le comme ceci:

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

    if (disableKeyBoard) {

        disableKeyboard = NO;
        return NO;

    } else {

        return YES;

    }

}

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

    disableKeyboard = YES;

}

Ceci est juste une solution de contournement et ne résout pas le problème principal, quel qu'il soit. Pour que cette méthode fonctionne, vous devez définir les méthodes de délégué alertView et textField dans votre en-tête.

0
Mike E