vol
vol

Reputation: 1904

RxSwift text ControlProperty have a different behaviour for UITextView and for UITextField

I want to modify the output by always adding "+1" at the end of each change. It works perfectly for UITextField but for the UITextView it's emitting infinite amount of times.

Can somebody explain how can I make UITextView behave the same as the UITextField in this example?

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
    @IBOutlet private weak var textField: UITextField!
    @IBOutlet private weak var textView: UITextView!

    private let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()
        problem()
        noproblem()
    }

    //This will write infinite number of 111111111 after typing anything
    private func problem() {
        textView.rx.text.map { text in
                    return text! + "1"
        }.asDriver(onErrorJustReturn: "-").drive(textView.rx.text).disposed(by: disposeBag)
    }

    //This will write 1 once per change, as expected!
    private func noproblem() {
        textField.rx.text.map { text in
                    return text! + "1"
        }.asDriver(onErrorJustReturn: "-").drive(textField.rx.text).disposed(by: disposeBag)
    }

}

When I debug I see that UITextView+Rx.swift have a condition for that but debugger lies or it doesn't work:

enter image description here enter image description here

Upvotes: 0

Views: 868

Answers (1)

hell0friend
hell0friend

Reputation: 569

textView.rx.text responds to all text changes including changes made by code. Try this:

textView.rx.didChange
    .asSignal()
    .map { [weak self] _ in
        guard let text = self?.textView.text else {
            return ""
        }
        return text + "1"
    }
    .emit(to: textView.rx.text)
    .disposed(by: disposeBag)

Upvotes: 1

Related Questions