No se puede ocultar el keyboard en la stack de UIViewController cuando UIAlertView está en la pantalla.

Acabo de pasar la mayor parte del día rastreando un caso muy extraño en el que llamar a resignFirstResponder en el UITextField activo no ocultaba el keyboard, aunque el campo de text era el primer respondedor. Esto sucede cuando presiono un controller de vista sobre otro controller de vista con un campo de text activo. El keyboard desaparece (como se esperaba). Pero si recupero el keyboard tocando un campo de text en el controller de la segunda vista, las llamadas posteriores a resignFirstResponder no tendrán ningún efecto.

Aquí hay un código simple para reproducir el problema. Este código es un controller de vista con un button de barra de navigation para ocultar el keyboard, y otro para impulsar otra copy de sí mismo (con una confirmación UIAlertView). La primera copy funciona sin problemas. Sin embargo, si presiona una segunda copy (cuando la primera copy tiene un keyboard visible), es imposible descartar el keyboard. Esto solo ocurre si hay un UIAlertView (la confirmación) en la pantalla cuando se empuja la segunda copy. Si elimina la línea #define ALERT , todo funciona.

¿Alguien sabe lo que está sucediendo aquí? Parece que la window UIALertView interfiere de alguna manera con el keyboard y evita que su window desaparezca, lo que confunde la siguiente vista. ¿Hay alguna solución aquí que no sea empujar el controller de la segunda vista en un timer después de que el UIALertView se haya ido?

Perdón por la compleja descripción. Este es un código ejecutable. Espero que el código sea claro.

 @implementation DemoViewController - (id) init { if (!(self = [super init])) return nil; return self; } - (void) dealloc { [_inputTextfield release]; [super dealloc]; } - (void) loadView { UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]; _inputTextfield = [[UITextField alloc] initWithFrame:CGRectMake(0., 0., 320., 44.)]; _inputTextfield.borderStyle = UITextBorderStyleRoundedRect; _inputTextfield.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; _inputTextfield.keyboardAppearance = UIKeyboardAppearanceAlert; _inputTextfield.autocapitalizationType = UITextAutocapitalizationTypeNone; _inputTextfield.autocorrectionType = UITextAutocorrectionTypeNo; _inputTextfield.keyboardType = UIKeyboardTypeDefault; [view addSubview:_inputTextfield]; self.view = view; [view release]; } - (void) viewWillAppear:(BOOL) animated { [super viewWillAppear:animated]; UIButton *downButton = [UIButton buttonWithType:UIButtonTypeCustom]; [downButton setTitle: @"keyboard down" forState:UIControlStateNormal]; [downButton addTarget:self action:@selector(downButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; [downButton sizeToFit]; self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:downButton] autorelease]; UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeCustom]; [nextButton setTitle: @"next" forState:UIControlStateNormal]; [nextButton addTarget:self action:@selector(nextButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; [nextButton sizeToFit]; self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:nextButton] autorelease];; } - (void) viewWillDisappear:(BOOL) animated { [super viewWillDisappear:animated]; [_inputTextfield resignFirstResponder]; } - (void) downButtonPressed:(id)sender { [_inputTextfield resignFirstResponder]; } #define ALERT - (void) alertView:(UIAlertView *) alertView didDismissWithButtonIndex:(NSInteger) buttonIndex { if (alertView.cancelButtonIndex == buttonIndex) { return; } [self _nextButtonPressed]; } - (void) _nextButtonPressed { DemoViewController *nextViewController = [[DemoViewController alloc] init]; [self.navigationController pushViewController:nextViewController]; [nextViewController release]; } - (void) nextButtonPressed:(id)sender { #ifdef ALERT UIAlertView *alert = [[UIAlertView alloc] init]; alert.message = @"Next view?"; alert.cancelButtonIndex = [alert addButtonWithTitle:@"No"]; [alert addButtonWithTitle:@"Yes"]; alert.delegate = self; [alert show]; [alert release]; #else [self _nextButtonPressed]; #endif } 

Si tuvo la mala suerte de renunciar a sus primeros respondedores, aquí hay algunas soluciones que podrían ayudar:

  1. Determine quién se ha mantenido como el primer respondedor después de su última llamada para renunciar al primer respondedor.

  2. Intente renunciar a todos los primeros respondedores mediante una sola llamada a self.view (vista de contenedor)

     [self.view endEditing:YES]; 
  3. SOLAMENTE si ha probado todos los methods anteriores y ninguno ha funcionado, considere usar esta solución alternativa.

     -(BOOL)textViewShouldEndEditing:(UITextView *)textView { NSArray *wins = [[UIApplication shanetworkingApplication] windows]; if ([wins count] > 1) { UIWindow *keyboardWindow = [wins objectAtIndex:1]; keyboardWindow.hidden = YES; } return YES; }