2010-06-25 15 views
5

Ich arbeite an einer Ansicht, die mehrere UITextField Objekte hat. Mein View-Controller dient als UITextFieldDelegate, und ich habe die (BOOL)textFieldShouldEndEditing:(UITextField *)textField-Methode implementiert, um den angezeigten Datensatz zu speichern und zu validieren.textFieldShouldEndEditing mehrmals aufgerufen

Wenn der Benutzer nach der Bearbeitung eines Elements auf die Schaltfläche "Fertig" klickt und die Sicherung/Validierung fehlschlägt, wird UIAlertView angezeigt und der Benutzer bleibt auf UITextField, die die Validierung nicht besteht.

Mein Problem ist, das - wenn ein Benutzer aus den UITextField klickt, speichern/Validierung auf einem anderen der UITextField s, dann ist die (BOOL)textFieldShouldEndEditing:(UITextField *)textField Methode wird aufgerufen, mehrere Male, und die UIAlertView erscheint mehrmals fehlschlagen.

Warum wird (BOOL)textFieldShouldEndEditing:(UITextField *)textField einmal aufgerufen, wenn der Benutzer auf der Tastatur auf "Fertig" klickt, aber mehrmals aufgerufen wird, wenn der Benutzer auf eine andere UITextField klickt?

Hier ist mein Code:

- (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; 
} 

Antwort

3

Ich denke, Ihr Problem aus der Ordnung kommt, in der Textfield-Methoden aufgerufen werden, wenn Sie ein Textfeld bearbeiten und direkt auf einem anderen tippen.

Wenn ich mich nicht irre, sollte es so etwas wie dieses (Sie auf A bearbeiten, und tippen Sie auf B)

  • textFieldShouldBeginEditing für Feld B
  • textFieldShouldEndEditing für Feld A
  • textFieldDidEndEditing für Feld Ein
  • textFieldDidBeginEditing für Feld B

Also, wenn yo Sie sind in textFieldShouldEndEditing Methode, Textfeld B ist bereits der Ersthelfer geworden. Wenn Sie also den UIAlertView erscheinen lassen, verliert B den Fokus und ruft somit auch textFieldShouldEndEditing auf!

Das war auch ein Problem für mich, als ich eine Ansicht erhöhen wollte, als ein TextField begann zu bearbeiten. Die Lösung, die ich gefunden habe, war, eine boolesche Klassenvariable zu erstellen, die anzeigt, ob ich gerade von einem Textfield zum anderen wechse oder nicht. Ich setze es auf TRUE in textFieldShouldBeginEditing und auf FALSE in textFieldDidBeginEditing. Wenn Sie in textFieldShouldEndEditing sind, wenn es auf TRUE eingestellt ist, bedeutet dies, dass der Benutzer direkt auf ein anderes TextField geklickt hat. Dann müssen Sie nur den richtigen Weg finden, Ihre Tests nur einmal zu machen (vielleicht sollte sendEditing false oder etwas zurückgeben).

0

Es sieht gut aus, dass ich zweimal für jedes Testfeld angerufen werde. Warum? man denke nur an ... hatte auch an mir vorbei und bekommen Kopfschmerzen mich

Sie NICHT

- (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;} 

einige, wie dies zu tun ist, dass die UIAlertView Show wird auch die Bearbeitung von Textfeld zum Rücktritt versucht und Aufruf dieser Funktion "textFieldShouldEndEditing:" ...

Also mein Weg, um dies zu lösen, war eine Member-Variable namens "sentEndEditing" in der Schnittstelle Delaration hinzufügen, wer als Standard ist. Und nach dem "textFieldShouldEndEditing:" kann so etwas sein.

- (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;} 

Viel Glück ...

1

Eine weitere Option ist die UIAlertView gefälschte eine korrekte Validierung und verschieben den Korrekturteil zu einem späteren Zeitpunkt zu lassen. Etwas wie folgt aus:

- (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

Könnten Sie nicht verschiedene Tags in jedem Textview hinzufügen und den Tag in der textFieldShouldEndEditing überprüfen? Oder habe ich den Punkt verpasst?

Verwandte Themen