将UITextField限制为仅字母和空格

问题描述

添加一个UITextField,我想将其限制为仅字母和空格。因此,以下内容

let set = CharacterSet (charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMnopQRSTUVWXYZ")

在不使用委托的情况下,以及在可能的情况下,使用RxSwift,RxCocoa等方法的情况下,如何做到这一点。

解决方法

您可以像这样检查:

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

并使用

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

您可以将事件添加到文本字段

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

处理更改后的文字

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

您可以在此处找到Rx文本过滤的一个很好的实现: RxSwift replacement shouldChangeCharactersInRange

在您的情况下,它应如下所示:

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