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?

user265961
quelle
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]];
Vladimir
quelle
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;
}
btmanikandan
quelle
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.

Focorner
quelle
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
25

Versuchen Sie, anstelle des UITextFieldDelegate das Ereignis "Editing Changed" von UITextField zu verwenden.

stumm schalten
quelle
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
}
bauerMusic
quelle
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
}
ioopl
quelle
5

Dies ist der Code, den Sie benötigen,

if ([textField isEqual:self.textField1])
  textField2.text = [textField1.text stringByReplacingCharactersInRange:range withString:string];
Deepak Danduprolu
quelle
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
    }
ober
quelle
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.

Boweidmann
quelle