Utilizzando `textField: shouldChangeCharactersInRange:`, come ottengo il testo che include il carattere attualmente digitato?


116

Sto usando il codice seguente per cercare di textField2aggiornare il contenuto del testo di textField1s ogni volta che l'utente digita textField1.

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

Tuttavia, l'output che osservo è che ...

textField2 è "12", quando textField1 è "123"

textField2 è "123", quando textField1 è "1234"

... quando quello che voglio è:

textField2 è "123", quando textField1 è "123"

textField2 è "1234", quando textField1 è "1234"

Che cosa sto facendo di sbagliato?


8
Solo un promemoria, è incredibilmente più facile usare sempre l' evento "Editing Changed" .. basta trascinarlo in IB su una funzione che crei.
Fattie

Notare che l'evento di modifica modificata non cattura alcun evento di modifica del testo generato a livello di programmazione, ad esempio correzione automatica / completamento automatico / sostituzione del testo.
spessore

Risposte:


272

-shouldChangeCharactersInRangeviene chiamato prima che il campo di testo cambi effettivamente il suo testo, ecco perché stai ottenendo il vecchio valore di testo. Per ottenere il testo dopo l'aggiornamento, utilizzare:

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

15
Questo ha quasi funzionato per me. Se ho digitato un carattere, ha funzionato. Se premessi il pulsante Elimina, eliminerei due caratteri. Per me, il seguente suggerimento ha funzionato: stackoverflow.com/questions/388237/... Fondamentalmente, drag'n'drop dal UITextField nel codice (per creare una funzione), quindi fare clic sul tuo TextField e drag'n' trascina dal cerchio per "Modifica modificata" alla tua nuova funzione. (Sigh. Mi manca Visual Studio a volte ..)
Mike Gledhill

Penso anche che questa sia una risposta valida, ma non LA risposta. Il modo migliore per ottenere ciò che desideri è stato risposto da @tomute
Pedro Borges

5
Oppure textFiel.text = (textFiel.text as NSString) .stringByReplacingCharactersInRange (range, withString: string) in Swift
Max

@MikeGledhill Puoi fare la stessa cosa in modo programmatico:[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

In base alla risposta accettata, in Swift 3 dovrebbe funzionare quanto segue :

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

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

    return true
}

Nota

Entrambi Stringe NSStringhanno metodi chiamati replacingCharacters:inRange:withString. Tuttavia, come previsto, il primo si aspetta un'istanza di Range, mentre il secondo si aspetta un'istanza di NSRange. Il textFieldmetodo delegato utilizza NSRangeun'istanza, quindi NSStringin questo caso l'uso di .


replacingCharactersdovrebbe esserestringByReplacingCharactersInRange
Alan Scarpa

1
@Alan_s Ho copiato questo snippet direttamente dal mio progetto Xcode e funzionava bene. Stai usando Xcode 8.1 con destinazione iOS 10.1?
focorner


13

In Swift (4), senza NSString(Swift puro):

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
}

Come estensione:

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

Versione rapida per questo:

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

Questo è il codice che ti serve,

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

1

usa la guardia

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

La mia soluzione è usare UITextFieldTextDidChangeNotification.

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

Non dimenticare di chiamare [[NSNotificationCenter defaultCenter] removeObserver:self];in deallocmetodo.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.