ChangeCharactersInRange 如何在 Swift 中工作?

问题描述 投票:0回答:10

我正在使用 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
}

在我得到一个值之前仍然调用该方法?

ios objective-c swift uitextfielddelegate nsrange
10个回答
209
投票

斯威夫特 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
    }
}

注意。使用安全文本字段时要小心。


80
投票

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
}

44
投票

斯威夫特 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
}

斯威夫特 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
为 nil(通过 nil 合并运算符
textField.text
),这就是为什么
??
被设置为空字符串的原因。

实施

textFieldShouldClear(_:)
处理文本字段的清除按钮可见并被点击的情况。


12
投票

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
}

1
投票

shouldChangeCharactersIn
在每次按键时被调用。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    // get the current text, or use an empty string if that failed
    let currentText = textField.text ?? ""

    // attempt to read the range they are trying to change, or exit if we can't
    guard let stringRange = Range(range, in: currentText) else { return false }

    // add their new text to the existing text
    let updatedText = currentText.replacingCharacters(in: stringRange, with: string)

    // make sure the result is under 16 characters
    return updatedText.count <= 16
}

1
投票

shouldChangeCharactersInRange

func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool { }

有改动但UI未更新时会调用此函数,等待您的选择

看看返回的布尔值

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
  • 如果你返回
    true
    - 这意味着 iOS 接受更改(文本,插入符号......)
  • 如果你回来
    false
    - 这意味着你要对所有这些东西负责

0
投票

斯威夫特 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


0
投票

这基本上是@Vyacheslav 为我自己的用例独立得出的答案,以防文体方法引起共鸣:-)

func textField(_ textField: UITextField, shouldChangeCharactersIn nsRange: NSRange, replacementString: String) -> Bool {
    let range = Range(nsRange, in: textField.text!)!
    let textWouldBecome =  textField.text!.replacingCharacters(in: range, with: replacementString)
    if textWouldBecome != eventModel.title {
        self.navigationItem.setHidesBackButton(true, animated: true)
    } else {
        self.navigationItem.setHidesBackButton(false, animated: true)
    }
    return true
}

将 eventModel.title 替换为您正在检查的更改显然。


0
投票

斯威夫特 13

func textFieldDidChangeSelection(_ textField: UITextField) {
    DispatchQueue.main.async { 
        self.textBinding.wrappedValue = textField.text ?? ""
    }
}

-7
投票

为了在 Swift 3.0 的 UITextField 组件中获取准确的文本,我使用了:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
   let enteredTxt = textField.text! + string
   doSomethingWithTxt(enteredTxt) //some custom method
}
© www.soinside.com 2019 - 2024. All rights reserved.