2011-10-29 20 views
5

Acabo de pasar la mayor parte del día buscando un caso muy extraño donde llamar a resignFirstResponder en el UITextField activo no ocultaba el teclado, aunque el campo de texto era el primero . Esto sucede cuando presiono un controlador de vista sobre otro controlador de vista con un campo de texto activo. El teclado se va (como se esperaba). Pero si devuelvo el teclado tocando un campo de texto en el segundo controlador de vista, las llamadas subsiguientes a resignFirstResponder no tienen efecto.No se puede ocultar el teclado en la pila UIViewController cuando UIAlertView está en la pantalla

Aquí hay un código simple para reproducir el problema. Este código es un controlador de vista con un botón de barra de navegación para ocultar el teclado y otro para enviar otra copia de sí mismo (con una confirmación UIAlertView). La primera copia funciona sin problemas. Sin embargo, si empuja una 2da copia (cuando la primera copia tiene un teclado visible) es imposible cerrar el teclado. Esto solo ocurre si hay un UIAlertView (la confirmación) en la pantalla cuando se empuja la 2da copia. Si quita la línea #define ALERT, todo funciona.

¿Alguien sabe lo que está sucediendo aquí? Parece que la ventana UIALertView está de alguna manera interfiriendo con el teclado y evitando que su ventana desaparezca, lo que confunde la siguiente vista. ¿Hay alguna otra solución aquí que no sea presionar el controlador de la segunda vista en un temporizador después de que UIALertView se haya ido?

Disculpe por la descripción compleja. 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 
} 
+0

Ha intentado renunciar al primer nivel de respuesta en el primer controlador de vista antes de presentar el segundo controlador de vista? –

+0

Sí, a la vista Va a desaparecer. Lo siento, eso no entró en mi código de demostración. Pero no tiene ningún efecto. – wombat57

+0

Ok, ¿ha intentado usar [self.view endEditing: YES]? esto debería finalizar la edición en todas las subvistas también. –

Respuesta

4

Si tuviera la mala suerte de renunciar a sus socorristas, aquí hay algunas soluciones que pueden ayudar:

  1. determinar quién ha seguido siendo el primer nivel de respuesta después de la última llamada a renunciar primer nivel de respuesta.

  2. Trate de renunciar todos los primeros en responder por una sola llamada a self.view (vista de contenedor)

    [self.view endEditing:YES]; 
    
  3. SOLO si usted ha intentado todos los métodos anteriores y ninguno funcionó, considere el uso de esta solución .

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