2011-10-29 11 views
5

Ho trascorso quasi tutto il giorno rintracciando un caso molto strano in cui la chiamata a resignFirstResponder sul campo UITextField attivo non nascondeva la tastiera, anche se il campo di testo era il primo risponditore . Ciò accade quando spingo un controller di visualizzazione sopra un altro controller di visualizzazione con un campo di testo attivo. La tastiera si spegne (come previsto). Ma se torno indietro la tastiera toccando un campo di testo nel 2 ° controller della vista, le successive chiamate a resignFirstResponder non hanno alcun effetto.Impossibile nascondere la tastiera nello stack UIViewController quando UIAlertView è sullo schermo

Ecco un semplice codice per riprodurre il problema. Questo codice è un controller di visualizzazione con un pulsante della barra di navigazione per nascondere la tastiera e un altro per spingere un'altra copia di se stesso (con un UIAlertView di conferma). La prima copia funziona senza problemi. Tuttavia, se si preme una seconda copia (quando la prima copia ha una tastiera visibile) è impossibile eliminare la tastiera. Questo succede solo se c'è un UIAlertView (la conferma) sullo schermo quando viene spinta la seconda copia. Se rimuovi la riga #define ALERT, tutto funziona.

Qualcuno sa cosa sta succedendo qui? Sembra che la finestra UIALertView interferisca in qualche modo con la tastiera e impedisca alla finestra di scomparire, il che confonde la vista successiva. C'è qualche soluzione qui oltre a spingere il secondo controller di visualizzazione su un timer dopo che UialertView è sparito?

Ci scusiamo per la descrizione complessa. Questo è un codice eseguibile. Spero che il codice sia chiaro.

@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

Hai provato dimissioni il primo risponditore sul primo controller della vista prima di presentare il secondo controller della vista? –

+0

Sì, in viewWillDisappear. Scusa, non è stato inserito nel mio codice demo. Ma non ha alcun effetto. – wombat57

+0

Ok, hai provato a usare [self.view endEditing: YES]? questo dovrebbe terminare anche la modifica su tutte le sottoview. –

risposta

4

Se avete avuto la sfortuna dimissionario tuoi primi soccorritori, qui ci sono alcune soluzioni che potrebbero aiutare:

  1. determinare chi è rimasto il primo responder dopo l'ultima chiamata a dare le dimissioni prima responder.

  2. Prova dimettersi tutti i primi interventi per una singola chiamata a self.view (vista del contenitore)

    [self.view endEditing:YES]; 
    
  3. SOLO se hai provato tutti i metodi di cui sopra e nessuno ha funzionato, considerare l'utilizzo di questa soluzione alternativa .

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