2010-06-25 3 views
5

Sto lavorando su una vista che ha più oggetti UITextField. Il mio controller di visualizzazione funge da UITextFieldDelegate e ho implementato il metodo (BOOL)textFieldShouldEndEditing:(UITextField *)textField per salvare e convalidare il record visualizzato.textFieldShouldEndEditing chiamato più volte

Se l'utente fa clic sul pulsante "Fatto" dopo aver modificato un elemento e il salvataggio/convalida non riesce, viene visualizzato un UIAlertView e l'utente viene mantenuto su UITextField che non riesce la convalida.

mio problema è questo - quando un utente fa clic dal UITextField che fallirà Salva/validazione su un altro dei UITextField s, allora il metodo (BOOL)textFieldShouldEndEditing:(UITextField *)textField viene chiamato più volte, e il UIAlertView apre più volte.

Perché (BOOL)textFieldShouldEndEditing:(UITextField *)textField viene chiamato una volta quando l'utente fa clic su "Fatto" sulla tastiera, ma chiama più volte quando l'utente fa clic su un altro UITextField?

Ecco il mio codice:

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField { 
    NSLog(@"textFieldShouldEndEditing called by textField with text=%@", textField.text); 

    currentItem.nameOrNumber = nameOrNumber.text; 

    // Try to save the managed object. 
    NSError *error = nil; 
    if (![[currentItem managedObjectContext] save:&error]) {   
     UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Uh Oh!",@"") 
                  message:[error localizedDescription] 
                  delegate:self 
                cancelButtonTitle:NSLocalizedString(@"OK",@"") 
                otherButtonTitles:nil]; 
     [errorAlert show]; 
     [errorAlert release]; 
     shouldEnd = NO; 
    } 

    return shouldEnd; 
} 

risposta

3

Credo che il problema deriva dall'ordine in cui i metodi textField vengono chiamati quando si modifica un textField e toccare direttamente su un altro.

Se non mi sbaglio, dovrebbe essere qualcosa di simile (che si sta modificando in A e toccare B)

  • textFieldShouldBeginEditing per il campo B
  • textFieldShouldEndEditing per il campo A
  • textFieldDidEndEditing per il campo Un
  • textFieldDidBeginEditing per il campo B

Così, quando yo sei nel metodo textFieldShouldEndEditing, il campo di testo B è già diventato il primo risponditore. Quindi, quando fai apparire UIAlertView, B perde la messa a fuoco e quindi chiama anche textFieldShouldEndEditing!

Anche questo è stato un problema per me quando volevo alzare una vista quando un campo di testo ha iniziato la modifica. La soluzione che ho trovato è stata quella di creare una variabile di classe booleana che indica se attualmente sto passando da un campo di testo a un altro. L'ho impostato su TRUE in textFieldShouldBeginEditing e su FALSE in textFieldDidBeginEditing. Quando sei in , se è impostato su TRUE significa che l'utente ha toccato direttamente un altro campo di testo. Quindi devi solo trovare il modo giusto per fare i tuoi test una sola volta (forse dovrebbeEndEditing dovrebbe restituire falso o qualcosa del genere).

0

Mi sembra giusto essere chiamato 2 volte per ogni campo di prova. Perché? Basti pensare ... era passato anche a me e farmi mal di testa

non si può fare un po 'come questo

- (BOOL)textFieldShouldEndEditing:(UITextField *)txtField{ 

if(i_dont_know){ 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title" 
                message:@"Message" 
                delegate:self 
              cancelButtonTitle:@"Ok" otherButtonTitles: nil]; 
    [alert show]; 
    [alert release]; 
    return false; 
} 

return true;} 

è che lo spettacolo UIAlertView sta anche cercando di dimettersi redazione del campo di testo e chiamando questa funzione "textFieldShouldEndEditing:" ...

Quindi il mio modo per risolvere questo problema è stato aggiungere una variabile membro chiamata "shouldEndEditing" nel delaration dell'interfaccia, che è true per default. E dopo "textFieldShouldEndEditing:" può essere un po 'come questo.

- (BOOL)textFieldShouldEndEditing:(UITextField *)txtField{ 

if(shouldEndEditing == false) 
{ 
    shouldEndEditing = true; 
    return false; 
} 

if(i_dont_know){ 
    shouldEndEditing = false; 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title" 
                message:@"Message" 
                delegate:self 
              cancelButtonTitle:@"Ok" otherButtonTitles: nil]; 
    [alert show]; 
    [alert release]; 
    return false; 
} 

return true;} 

Buona fortuna ...

1

Un'altra opzione è quella di lasciare che il UIAlertView finto una corretta validazione e rinviare la parte di correzione a una seconda volta. Qualcosa di simile a questo:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ 
    double delayInSeconds = 0.; 
    self.currentTextField.text = @"Something that won't trigger validation error"; 
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
     // do what you need here 
    }); 
} 
0

Non potresti aggiungere tag diversi in ogni TextView e controllare il tag nella textFieldShouldEndEditing? O ho perso il punto?