J'utilise shouldChangeCharactersInRange comme moyen d'utiliser la recherche de type à la volée.
Cependant, j'ai un problème, shouldChangeCharactersInRange est appelé avant que le champ de texte ne soit mis à jour:
En Objective C, j'ai résolu ce problème en utilisant ci-dessous:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString * searchStr = [textField.text stringByReplacingCharactersInRange:range withString:string];
return YES;
}
Cependant, j'ai essayé d'écrire ceci dans Swift:
func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
let txtAfterUpdate:NSString = self.projectSearchTxtFld.text as NSString
txtAfterUpdate.stringByReplacingCharactersInRange(range, withString: string)
self.callMyMethod(txtAfterUpdate)
return true
}
La méthode est toujours appelée avant que je reçoive une valeur?
Swift 4
Cette méthode n'utilise pas NSString
// MARK: - UITextFieldDelegate
extension MyViewController: UITextFieldDelegate {
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
if let text = textField.text,
let textRange = Range(range, in: text) {
let updatedText = text.replacingCharacters(in: textRange,
with: string)
myvalidator(text: updatedText)
}
return true
}
}
Remarque. Soyez prudent lorsque vous utilisez un champ de texte sécurisé.
stringByReplacingCharactersInRange
retourne une nouvelle chaîne, alors que diriez-vous de:
func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
if let text = textField.text as NSString? {
let txtAfterUpdate = text.replacingCharacters(in: range, with: string)
self.callMyMethod(txtAfterUpdate)
}
return true
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let textFieldText: NSString = (textField.text ?? "") as NSString
let txtAfterUpdate = textFieldText.replacingCharacters(in: range, with: string)
callMyMethod(txtAfterUpdate)
return true
}
func textFieldShouldClear(_ textField: UITextField) -> Bool {
callMyMethod("")
return true
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let textFieldText: NSString = textField.text ?? ""
let txtAfterUpdate = textFieldText.stringByReplacingCharactersInRange(range, withString: string)
callMyMethod(txtAfterUpdate)
return true
}
func textFieldShouldClear(textField: UITextField) -> Bool {
callMyMethod("")
return true
}
Bien que la propriété textField.text
soit facultative, elle ne peut pas être définie sur nil. Si vous définissez cette option sur nil, la chaîne vide dans UITextField
est modifiée. Dans le code ci-dessus, c'est pourquoi textFieldText
est défini sur chaîne vide si textField.text
est nul (via l'opérateur de coalescence nil ??
).
L'implémentation textFieldShouldClear(_:)
traite le cas où le bouton vide du champ de texte est visible et exploité.
Dans Swift 3 cela ressemblerait à ceci:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let text: NSString = (textField.text ?? "") as NSString
let resultString = text.replacingCharacters(in: range, with: string)
return true
}
Si vous souhaitez pré-traiter les caractères saisis ou collés par l'utilisateur, la solution suivante fonctionne comme un charme
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let strippedString = <change replacements string so it fits your requirement - strip, trim, etc>
// replace current content with stripped content
if let replaceStart = textField.position(from: textField.beginningOfDocument, offset: range.location),
let replaceEnd = textField.position(from: replaceStart, offset: range.length),
let textRange = textField.textRange(from: replaceStart, to: replaceEnd) {
textField.replace(textRange, withText: strippedString)
}
return false
}
Trouvez-le ici: https://Gist.github.com/Blackjacx/2198d86442ec9b9b05c0801f4e392047