Как shouldChangeCharactersInRange работает в Swift?
Я использую shouldChangeCharactersInRange как способ использования поиска типа "на лету".
однако у меня возникли проблемы,shouldChangeCharactersInRange вызывается до фактического обновления текстового поля:
в Objective C, я решил это с помощью использования ниже:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString * searchStr = [textField.text stringByReplacingCharactersInRange:range withString:string];
return YES;
}
тем не менее, я попытался написать это в 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
}
метод все еще вызывается, прежде чем я получу значение?
6 ответов:
Swift 4
этот метод не использовать
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 } }
Примечание. Будьте осторожны при использовании защищенного текстового поля.
stringByReplacingCharactersInRange
вернуть новую строку, так как насчет: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 }
Swift 3 & 4
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 }
Swift 2.2
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 }
хотя
textField.text
свойство является необязательным, оно не может быть установлено в nil. Значение nil изменяется на пустую строку в пределахUITextField
. В приведенном выше коде, именно поэтомуtextFieldText
устанавливается в пустую строку, еслиtextField.text
равно нулю (через оператор слияния нулей??
).реализация
textFieldShouldClear(_:)
обрабатывает случай, когда кнопка очистки текстового поля видна и нажата.
In Swift 3 это будет выглядеть так:
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 }
Swift 3
если вы хотите предварительно обработать символы напечатаны или наклеены, следующее решение работает как шарм
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 }
найти его здесь:https://gist.github.com/Blackjacx/2198d86442ec9b9b05c0801f4e392047
чтобы получить точный текст в компоненте my UITextField в Swift 3.0 я использовал:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let enteredTxt = textField.text! + string doSomethingWithTxt(enteredTxt) //some custom method }