Mehmet Ceylan
Mehmet Ceylan

Reputation: 395

Limit UITextField to letters and spaces only

I added a UITextField and I want to restrict it to only alphabets and spaces. So with the following;

let set = CharacterSet (charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ")

How can I do this without using delegates if possible and if possible using a method like RxSwift, RxCocoa etc .. Does anyone have a brilliant idea?

Upvotes: 0

Views: 1146

Answers (3)

Adis
Adis

Reputation: 4552

You can find a pretty good implementation of Rx text filtering here: RxSwift replacement shouldChangeCharactersInRange

In your case, it should look like this:

textField.rx.text.orEmpty
    .map(alphaNumericAndWhitespace)
    .subscribe(onNext: setPreservingCursor(on: textField))
    .disposed(by: bag)

func alphaNumericAndWhitespace(_ text: String) -> String {
    let customSet = CharacterSet.alphanumerics.union(CharacterSet.whitespaces)
    return text.components(separatedBy: customSet.inverted).joined(separator: "")
}

func setPreservingCursor(on textField: UITextField) -> (_ newText: String) -> Void {
    return { newText in
        let cursorPosition = textField.offset(from: textField.beginningOfDocument, to: textField.selectedTextRange!.start) + newText.count - (textField.text?.count ?? 0)
        textField.text = newText
        if let newPosition = textField.position(from: textField.beginningOfDocument, offset: cursorPosition) {
            textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)
        }
    }
}

Upvotes: 0

Kishan Bhatiya
Kishan Bhatiya

Reputation: 2368

You can check like this:

func validateField(enteredString:String) -> Bool {
    
    let validationFormat = "[a-zA-Z\\s]+"
    let fieldPredicate = NSPredicate(format:"SELF MATCHES %@", validationFormat)
    return fieldPredicate.evaluate(with: enteredString)
}

And use

if !validateField(enteredString: textField.text ?? "") {
            
    print("Invalid String")
    return false
}

Upvotes: 1

Vibhor
Vibhor

Reputation: 70

You can add an event to the textfield

textField1.addTarget(self, action: #selector(YourViewController.textFieldDidChange(_:)), forControlEvents: UIControlEvents.EditingChanged)

Handle the text when it gets changed

func textFieldDidChange(textField: UITextField) {
    // Check the textField text and update textField
}

Upvotes: 0

Related Questions