Wie erhalte ich mit `textField: shouldChangeCharactersInRange:` den Text einschließlich des aktuell eingegebenen Zeichens?


116

Ich verwende den folgenden Code, um zu versuchen textField2, den Textinhalt bei textField1jeder Eingabe durch den Benutzer so zu aktualisieren, dass er mit dem übereinstimmt textField1.

- (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange: (NSRange)range replacementString: (NSString *)string {    
  if (theTextField == textField1){    
     [textField2 setText:[textField1 text]];    
  }
}

Die Ausgabe, die ich beobachte, ist jedoch, dass ...

textField2 ist "12", wenn textField1 "123" ist.

textField2 ist "123", wenn textField1 "1234" ist.

... wann ich will:

textField2 ist "123", wenn textField1 "123" ist.

textField2 ist "1234", wenn textField1 "1234" ist.

Was mache ich falsch?


8
Nur zur Erinnerung, es ist erstaunlich einfacher, das Ereignis "Bearbeiten geändert" immer zu verwenden . Ziehen Sie es einfach in IB auf eine von Ihnen erstellte Funktion.
Fattie

Beachten Sie, dass das Ereignis zum Bearbeiten von Änderungen keine programmgesteuert generierten Textänderungsereignisse erfasst, z. B. Autokorrektur / Autovervollständigung / Textersetzung.
Shim

Antworten:


272

-shouldChangeCharactersInRangewird aufgerufen, bevor das Textfeld seinen Text tatsächlich ändert. Deshalb erhalten Sie den alten Textwert. Um den Text nach dem Update zu erhalten, verwenden Sie:

[textField2 setText:[textField1.text stringByReplacingCharactersInRange:range withString:string]];

15
Das hat bei mir fast geklappt. Wenn ich ein Zeichen eingegeben habe, hat dies funktioniert. Wenn ich die Löschtaste drückte, wurden zwei Zeichen gelöscht. Für mich hat der folgende Vorschlag funktioniert: stackoverflow.com/questions/388237/… Ziehen Sie im Grunde genommen aus dem UITextField in Ihren Code (um eine Funktion zu erstellen), klicken Sie mit der rechten Maustaste auf Ihr TextField und ziehen Sie es. Wechseln Sie aus dem Kreis für "Bearbeiten geändert" zu Ihrer neuen Funktion. (Seufz. Ich vermisse Visual Studio manchmal ..)
Mike Gledhill

Ich denke auch, dass dies eine gültige Antwort ist, aber nicht DIE Antwort. Der beste Weg, um das zu erreichen, was Sie wollen, wurde von @tomute
Pedro Borges

5
Oder textFiel.text = (textFiel.text als NSString) .stringByReplacingCharactersInRange (Bereich, withString: string) in Swift
Max

@ MikeGledhill Sie können das gleiche programmgesteuert tun:[textField addTarget:self action:@selector(textFieldEditingChanged:) forControlEvents:UIControlEventEditingChanged]
Steve Moser

52
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSString * searchStr = [textField.text stringByReplacingCharactersInRange:range withString:string];

    NSLog(@"%@",searchStr);
    return YES;
}

40

Swift 3

Basierend auf der akzeptierten Antwort sollte in Swift 3 Folgendes funktionieren :

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    let newString = NSString(string: textField.text!).replacingCharacters(in: range, with: string)

    return true
}

Hinweis

Beide Stringund NSStringhaben Methoden aufgerufen replacingCharacters:inRange:withString. Wie erwartet erwartet der erstere jedoch eine Instanz von Range, während der letztere eine Instanz von erwartet NSRange. Die textFieldDelegate-Methode verwendet eine NSRangeInstanz, also die Verwendung von NSStringin diesem Fall.


replacingCharacterssollte seinstringByReplacingCharactersInRange
Alan Scarpa

1
@Alan_s Ich habe dieses Snippet direkt aus meinem Xcode-Projekt kopiert und es hat einwandfrei funktioniert. Verwenden Sie Xcode 8.1 mit Ziel für iOS 10.1?
Focorner


13

In Swift (4) ohne NSString(reines Swift):

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    if let textFieldString = textField.text, let swtRange = Range(range, in: textFieldString) {

        let fullString = textFieldString.replacingCharacters(in: swtRange, with: string)

        print("FullString: \(fullString)")
    }

    return true
}

Als Erweiterung:

extension UITextField {

    func fullTextWith(range: NSRange, replacementString: String) -> String? {

        if let fullSearchString = self.text, let swtRange = Range(range, in: fullSearchString) {

            return fullSearchString.replacingCharacters(in: swtRange, with: replacementString)
        }

        return nil
    }
}

// Usage:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    if let textFieldString = textField.fullTextWith(range: range, replacementString: string) {
        print("FullString: \(textFieldString)")
    }

    return true
}

8

Schnelle Version dafür:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    if string == " " {
        return false
    }

    let userEnteredString = textField.text

    var newString = (userEnteredString! as NSString).stringByReplacingCharactersInRange(range, withString: string) as NSString

    print(newString)

    return true
}

5

Dies ist der Code, den Sie benötigen,

if ([textField isEqual:self.textField1])
  textField2.text = [textField1.text stringByReplacingCharactersInRange:range withString:string];

1

Wache benutzen

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        guard case let textFieldString as NSString = textField.text where
            textFieldString.stringByReplacingCharactersInRange(range, withString: string).length <= maxLength else {
                return false
        }
        return true
    }

0

Meine Lösung ist zu verwenden UITextFieldTextDidChangeNotification.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(copyText:) name:UITextFieldTextDidChangeNotification object:nil];

Vergessen Sie nicht, rufen Sie [[NSNotificationCenter defaultCenter] removeObserver:self];in deallocMethode.


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.