UITextField "Wert geändert" wird nicht ausgelöst, wenn das Feld aktualisiert wird


72

Ich habe eine IBAction, die ich mit einem UITextFieldElement in Interface Builder verbunden habe. (Auslösen bei Ereignis "Wert geändert")

Ich habe auch eine UISlider, die das TextField-Element automatisch aktualisiert, wenn sein Wert angepasst wird.

Wenn ich meine App starte, wird das TextField aktualisiert, wenn ich den Schieberegler anpasse, aber das Ereignis "Wert geändert" wird in diesem Fall nicht ausgelöst. Das Ereignis "Wert geändert" wird auch nicht ausgelöst, wenn ich das TextField ebenfalls von Hand bearbeite. (Obwohl der Trigger Did Editing End verwendet wird, wird er ausgelöst.)

Meine Frage ist, wie ich den Wertänderungsauslöser sowohl für eine programmatische Aktualisierung des TextFields als auch für den Zeitpunkt, zu dem der Benutzer den Wert anpasst, auslösen kann.


Hallo, warum haben Sie keine UITextFieldDelegate-Methoden verwendet?
TheRonin

2
Sie dienen verschiedenen Zwecken. shouldChangeCharactersInRangeMit dieser Option können Sie entscheiden, ob Änderungen vorgenommen werden sollen oder nicht, und Sie müssen das Ergebnis selbst berechnen. Wenn die Änderung also immer stattfinden wird und Sie sich nur um den geänderten Wert kümmern, ist die Verwendung UIControlEventEditingChangeddefinitiv einfacher.
Superarts.org

Antworten:


0

Verwenden UITextFieldDelegateund implementieren Sie, wie von TheRonin vorgeschlagen, die folgende Methode

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

Implementiere ich dies in meinem View Controller?
Andrew Lauer Barinov

Ja. Fügen <UITextFieldDelegate>Sie die Deklaration der .h-Dateischnittstelle hinzu. Legen Sie den Delegaten des Textfelds über die NIB-Datei auf den Dateieigentümer fest. Implementieren Sie die oben genannte Methode im Viewcontroller.
Ilanchezhian

1
Funktioniert dies auch, wenn das Textfeld programmgesteuert aktualisiert wird?
Andrew Lauer Barinov

3
Wäre es nicht logischer, diesen zu verwenden? UITextFieldTextDidChangeNotificationIch bin mir jedoch nicht sicher, wie ich es umsetzen soll.
Andrew Lauer Barinov

18
Das Problem bei dieser Methode ist, dass sie aufgerufen wird, bevor das eingegebene Zeichen festgeschrieben wird. Das heißt, wenn Sie tippen found dann tippen o, textField.textist das still found noch nicht foo. Sie müssten die Änderung manuell anwenden, um die Zeichenfolge zu erhalten, auf die das Textfeld gesetzt wird.
DarkDust

220

Nicht verwenden UIControlEventValueChangedfür UITextField. Was du willst ist UIControlEventEditingChanged.


4
Ich argumentiere nicht, ob es funktioniert oder nicht, aber ich möchte nur wissen, warum dies der Fall ist?
Trojaner

3
Ich habe es versucht und es wird nicht ausgelöst, wenn das Textfeld programmgesteuert geändert wird.
Andrew Lauer Barinov

3
Richtig, keines der Ziel- / Aktionsereignisse wird für programmatische Änderungen von Entwurf aufgerufen.
Mark Adams

6
Dies sollte die akzeptierte Antwort sein. UITextFieldDelegatemacht ganz andere Sache.
Superarts.org

71

Um zu erhalten EditingChanged textfield event, schlug ich vor, Selektor als hinzuzufügen

[textField addTarget:self action:@selector(textChanged:) forControlEvents:UIControlEventEditingChanged];

Wenn sich der Textfeldwert ändert, wird der geänderte Wert von diesem textChanged:Selektor angezeigt .

-(void)textChanged:(UITextField *)textField
{
    NSLog(@"textfield data %@ ",textField.text);
}

Einfachste Lösung und feuert genau dann, wenn Sie es erwarten würden!
RyJ

1
Ich frage mich, warum sie Wert geändert Ereignis für haben, wenn es nicht funktioniert
Shiva

11

Wenn Sie dem Textfeld einen Delegaten zuweisen, beachten Sie, dass (wenn Sie NO von der folgenden Delegate-Methode zurückgeben, das Ereignis (Änderung geändert) nicht ausgelöst wird. Erwägen Sie, den Ereignis-Listener aufzurufen, wenn Sie NO von dieser Methode zurückgeben

(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

3
Das Ereignis "Bearbeiten geändert" wird nicht ausgelöst, da sich das Feld nicht geändert hat - genau das bewirkt die Rückgabe von NEIN!
Olie

@olie - Manchmal ändern Sie das Feld jedoch programmgesteuert in dieser Delegatmethode und geben dann NO zurück, um den Standardtext des Benutzers zu überschreiben. Dies war mein Fall und diese Antwort löste das Problem.
Clay Garrett

Sicher, aber das ist keine Bearbeitungsänderung . Wenn Sie dies tun möchten, sollte Ihr Code auch den geänderten Selektor des Delegaten aufrufen. Auf diese Weise haben Sie die volle Kontrolle.
Olie

3

Eine alte Frage, aber das erste Suchergebnis, das ich gefunden habe, und keine der Antworten ist zufriedenstellend. Ich fand, dass diese Lösung am besten funktioniert: Swift UITextField-Unterklassen behandeln Textänderungen programmgesteuert .

Überschreiben Sie die Texteigenschaft von UITextField, um ein didSet () hinzuzufügen, und rufen Sie von dort aus Ihre Funktion zur Wertänderung auf.

  override open var text: String? {
        didSet {
            myValueDidChange()
        }
    }

1

Während der Wert programmgesteuert zugewiesen wird, wird in diesem Fall textFieldDidChange nie aufgerufen, da sich textField tatsächlich nicht geändert hat. Für dieses externe Ereignis muss bestanden werden

Beispiel: textfield.sendActions (für: .editingChanged) Dies löst das bearbeitete geänderte Ereignis aus und textFieldDidChange wird aufgerufen, selbst nachdem der Wert programmgesteuert geändert wurde.

Wo diese Veranstaltung gelten :

Nach dem Zuweisen eines Wertes zu dem abgelegten Text, z. B. textfield.text = "irgendein Wert"


0

Swift 4:

class YourViewController: UIViewController {
    // MARK: Outlets
    @IBOutlet weak var titleTextField: UITextField!

    // MARK: View lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        titleTextField.delegate = self
    }
}

// MARK: UITextFieldDelegate methods
extension YourViewController: UITextFieldDelegate {
    func textField(_ textField: UITextField,
                   shouldChangeCharactersIn range: NSRange,
                   replacementString string: String) -> Bool {
        print("changed")
        return true
    }
}

-3

Für Swift 3 :

textField.addTarget(self, action: #selector(textChanged), for: .valueChanged)

func textChanged() { 
 .... 
}

4
Wenn Sie während der Bearbeitung Eingaben erhalten möchten, müssen Sie diese verwenden for: .editingChanged.
Changnam Hong

@ChangnamHong nein, es funktioniert jetzt nicht, sollten Sie verwenden.valueChanged
UnRewa
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.