Подтвердить что ты не робот

Как должно работатьShangeCharactersInRange в 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
}

Метод все еще вызывается до того, как я получу значение?

4b9b3361

Ответ 1

Свифт 4, Свифт 5

Этот метод не использует 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
    }
}

Заметка. Будьте осторожны при использовании защищенного текстового поля.

Ответ 2

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
}

Ответ 3

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 равно nil (через оператор объединения nil ??).

Реализация textFieldShouldClear(_:) обрабатывает случай, когда кнопка очистки текстового поля отображается и отображается.

Ответ 4

В 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
}

Ответ 5

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

Ответ 6

Я только что прочитал эту ветку, которая действительно полезна, может кто-нибудь определить, если мы сделаем что-то подобное для проверки максимальной длины текстового поля, которая также решает эту проверку максимального поля.

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

 let maxCharacter = 30

return (self.txtFieldUserName.text?.count)! <= maxCharacter

}

дайте мне знать, если это создает какие-либо проблемы в этом сценарии

Очень ценю заранее. Спасибо

Ответ 7

Чтобы получить точный текст в моем компоненте 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
}