How shouldChangeCharactersInRange works in Swift?

Ryan picture Ryan · Sep 2, 2014 · Viewed 76.3k times · Source

I'm using shouldChangeCharactersInRange as a way of using on-the-fly type search.

However I'm having a problem, shouldChangeCharactersInRange gets called before the text field actually updates:

In Objective C, I solved this using using below:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSString * searchStr = [textField.text stringByReplacingCharactersInRange:range withString:string];

    return YES;
}

However, I've tried writing this in 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
}

The method still gets called before I get a value?

Answer

Vyacheslav picture Vyacheslav · Feb 2, 2018

Swift 4, Swift 5

This method doesn't use 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
    }
}

Note. Be careful when you use a secured text field.