06.RxSwift textFiled和textView的差別

override func viewDidLoad() {
        super.viewDidLoad()
	    // 1: textFiled & textView來了
        // 2: why 來兩次
        textFiled.rx.text.subscribe(onNext: { (text) in
            print("輸入來了 \(text)")
        })
        textView.rx.text.subscribe(onNext: { (text) in
            print("textView:輸入來了 \(text)")
        })
        textFiled.addTarget(self, action: #selector(textFiledChange), for: .allEditingEvents)
}

@objc func textFiledChange() {
        print("laile")
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        textFiled.text = "LiHua"
        //textFiled.sendActions(for: .allEditingEvents)
        textView.text = "LiMing"
}
複製代碼
  • 問題一:剛運行起來就會打印:

textFiled輸入來了 Optional("") textView:輸入來了 Optional("Lorem ipsu...git

緣由是:初始化序列的時候 -> 默認會發送一次.onNext,讓信號成爲熱信號(激活) 解決辦法:加一個skip(1)便可,防止建立的時候默認調用一次bash

//加一個skip(1)便可,防止建立的時候默認調用一次
 textFiled.rx.text.skip(1). subscribe(onNext: { (text) in
      print("輸入來了 \(text)")
 })
複製代碼
  • 問題二:執行賦值textFiled.text = "LiHua"textView.text = "LiMing" 卻只有一個打印了 運行結果以下:

textView:輸入來了 Optional("LiMing")app

緣由是:Rx內部textView.texttextFiled.text處理不同async

  • textView.text 內部使用的是 uses text storage notification儲存通知
/// Reactive wrapper for `text` property.
    public var value: ControlProperty<String?> {
        let source: Observable<String?> = Observable.deferred { [weak textView = self.base] in
            let text = textView?.text
            let textChanged = textView?.textStorage
                // This project uses text storage notifications because
                // that's the only way to catch autocorrect changes // in all cases. Other suggestions are welcome. .rx.didProcessEditingRangeChangeInLength // This observe on is here because text storage // will emit event while process is not completely done, // so rebinding a value will cause an exception to be thrown. .observeOn(MainScheduler.asyncInstance) .map { _ in return textView?.textStorage.string } ?? Observable.empty() return textChanged .startWith(text) } 複製代碼
  • textFiled.text 使用的是Events,只是作了賦值操做
/// Reactive wrapper for `text` property.
    public var value: ControlProperty<String?> {
        return base.rx.controlPropertyWithDefaultEvents(
            getter: { textField in
                textField.text
            },
            setter: { textField, value in
                // This check is important because setting text value always clears control state
                // including marked text selection which is imporant for proper input 
                // when IME input method is used.
                if textField.text != value {
                    textField.text = value
                }
            }
        )
    }
複製代碼

解決辦法: RxSwiftgitHubIssues一欄有以下:ide

即:設置 textFiled.sendActions(for: .allEditingEvents)

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        textFiled.text = "LiHua"
        textFiled.sendActions(for: .allEditingEvents)
        textView.text = "LiMing"
    }
複製代碼
相關文章
相關標籤/搜索