En iOS 8.3 y posterior, UIAlertView hace que keyboardWillShow & keyboardWillHide se llame dos veces

Mientras trabajaba en un proyecto, me encontré con este problema.

Uno de los controlleres implementa el keyboardWillShow Will keyboardWillShow & keyboardWillShow Will keyboardWillHide (Código estándar de Apple que gestiona el keyboard ). En Background tap, UIAlertView aparece (basado en alguna validation), solo hay un button en UIAlertView que simplemente cierra UIAlertView .

Se produce un problema aquí, al cierre de UIAlertView , se UIAlertView keyboardWillShow & keyboardWillHide .

A continuación se muestra el código que tengo problema,

 #import "ViewController.h" @interface ViewController () <UITextFieldDelegate> { int timeCalledShow; int timeCalledHide; } @property (weak, nonatomic) IBOutlet UITextField *textField; @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; - (IBAction)backgroundTapped:(id)sender; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardDidHideNotification object:nil]; } - (void)keyboardWillShow:(NSNotification *)notification { timeCalledShow+=1; NSLog(@"show Time Called %d", timeCalledShow); CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; UIEdgeInsets contentInsets; if (UIInterfaceOrientationIsPortrait([[UIApplication shanetworkingApplication] statusBarOrientation])) { contentInsets = UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.height), 0.0); } else { contentInsets = UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.width), 0.0); } self.scrollView.contentInset = contentInsets; self.scrollView.scrollIndicatorInsets = contentInsets; } - (void)keyboardWillHide:(NSNotification *)notification { timeCalledHide+=1; NSLog(@"Hide Time Called %d", timeCalledShow); self.scrollView.contentInset = UIEdgeInsetsZero; self.scrollView.scrollIndicatorInsets = UIEdgeInsetsZero; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (IBAction)backgroundTapped:(id)sender { [[[UIAlertView alloc] initWithTitle:@"Testing" message:@"Keyboard hide & show, due to alert view" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil] show]; [self.view endEditing:YES]; } @end 

Notas

  1. Ya he comprobado keyboardWillShow llamado dos veces y preguntas similares aquí, pero no pude encontrar la respuesta
  2. Funciona bien con iOS 7.0
  3. Aquí hay un enlace del Código de testing

Editar Ya conozco el trabajo en torno a los códigos. pero la verdadera pregunta es cómo un UIAlertView puede disparar un keyboardWillShow UIAlertView notificación

Edit Code He intentado el código Below también sugerido por @Chonch, pero con este keyboard de código nunca se cierra incluso. El keyboard de medios vuelve a aparecer después de cerrar Alert.

 - (IBAction)backgroundTapped:(id)sender { UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"testing" message:@"Keyboard" prefernetworkingStyle:UIAlertControllerStyleAlert]; UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {}]; [alert addAction:defaultAction]; [self presentViewController:alert animated:YES completion:nil]; [self.textField resignFirstResponder]; } 

Pregunta publicada en los foros de desarrolladores de Apple

UIAlertView es cochecito y probablemente no lo haya sido ya que estaba en desuso.
Reemplazarlo con UIAlertController y su problema debería desaparecer

No estoy seguro de por qué sucede. Probablemente tenga algo que ver con UIAlertView intentando recuperar el estado del keyboard a lo que era antes. Pero tenga en count que no hay ningún daño hecho con las llamadas show / hide adicionales. Y, en general, debes estar preparado para varias llamadas de show de todos modos, porque también vienen cuando se cambia el estilo del keyboard.

Si desea deshacerse de ellos, use un UIAlertController en su lugar, como ya lo sugirió Chonch, y asegúrese de que el keyboard se descarta antes de que aparezca la Alerta, entonces funcionará bien:

 - (IBAction)backgroundTapped:(id)sender { [self.textField resignFirstResponder]; alert = [UIAlertController alertControllerWithTitle:@"testing" message:@"Keyboard" prefernetworkingStyle:UIAlertControllerStyleAlert]; UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {}]; [alert addAction:defaultAction]; [self presentViewController:alert animated:YES completion:nil]; } 

Tenga en count que con UIAlertController, también debe mantener una reference a la alerta en el control de visualización, de lo contrario se desasignará demasiado pronto.

Acabo de arreglar un problema similar. El keyboard sigue emergente después de que se desestima la alerta. Parece un error de manzana.

Hay una solución simple: si está usando AlertController, simplemente puede configurar el animado como NO

 [self presentViewController:alert animated:NO completion:nil]; 

Avísame si solucionó tu problema