Dav*_*adi 6 ios swift rx-swift
我想将UITextfield与RxSwift一起使用。我的目标是让用户键盘/不输入字符和复制粘贴删除角色,我需要处理的UITextField的委托“shouldChangeCharactersInRange”与RxSwift。
如何用RxSwift实现?
我正在使用版本4的RxSwift。情况1:来自键盘的输入:A123来自RxSwift的进程:接受123(不允许数字键盘)输出:123
情况2:从联系人处输入表单复制粘贴:\ U202d1111111111 \ U202c从RxSwift处理:删除所有控制字符,接受1111111111输出:1111111111
如果总的来说,我们可以使用shouldChangeCharactersInRange,但是如何与RxSwift一起使用呢?
通常,shouldChangeCharactersInRange即使您不使用Rx,也不应在中更改状态。该回调是查询而不是命令。该文本字段只是询问您是否应执行默认行为,而不是告诉您对其进行更新。您尝试实现的行为应该在editChanged操作中。
由于使用的是Rx,因此文本字段的rx.text观察者等效于editedChanged操作,应改为使用。该过程中最困难的部分是确保用户在字符串中间插入/删除时不要失去其位置。
在您的viewDidLoad中:
textField.rx.text.orEmpty
.map(digitsOnly)
.subscribe(onNext: setPreservingCursor(on: textField))
.disposed(by: bag)
Run Code Online (Sandbox Code Playgroud)
支持全局功能:
func digitsOnly(_ text: String) -> String {
return text.components(separatedBy: CharacterSet.decimalDigits.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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,即使您正在展示数字键盘,您仍然需要这样的代码,因为用户可能已经连接了蓝牙键盘,因此仍然可以输入非数字。
| 归档时间: |
|
| 查看次数: |
1831 次 |
| 最近记录: |