首页 > 解决方案 > 如何使用 RxSwift 让 ViewController 观察 ViewModel 变量(Variable<..>)的任何变化?

问题描述

如何从 ? 观察类内Variable<...>value( RxSwift Variable) 的变化?ViewModelViewController

因此,如果Variable<..>我在ViewModel发生的事情中发生的任何变化中ViewModel的任何值ViewController都会被注意到“嘿!ViewModel 中的一个或多个变量<..> 发生了变化!向 ViewModel 询问您需要的数据更新用户界面并更新用户界面!”

然后在ViewController 中ViewController调用一个方法updateUI(),并在其中询问ViewModel状态/状态等所有信息以更新 UI,例如:

func updateUI() {
  progressBar.hide = viewModel.getProgressBarVisibility()
  errorMessageLabel.hide = viewModel.getErrorMessageVisibility()
  errorMessageLabel.text = viewModel.getErrorMessageText()
  .....
  ...
}

标签: iosswiftobserver-patternrx-swift

解决方案


如果单个 ViewModel 的属性值发生变化,为什么要更新完整的 UI?

RxSwift 使您能够独立地监听更改,并且您可以相应地做出反应/更改 UI。

在我看来,这就是您的 ViewModel 和 ViewController 类的外观:

class ViewModel {
    private var progressBarVisibiity:Variable<Double> = Variable.init(0.0)
    private var errorMessageVisibiity:Variable<Double> = Variable.init(0.0)
    private var errorMessageLabel:Variable<String> = Variable.init("Default text")

    public func setProgressBarVisibiity(_ value:Double) {
        progressBarVisibiity.value = value
    }

    public func setErrorMessageVisibiity(_ value:Double) {
        errorMessageVisibiity.value = value
    }

    public func setErrorMessageLabel(_ value:String) {
        errorMessageLabel.value = value
    }

    public func observeProgressBarVisibiity() -> Observable<Double> {
        return progressBarVisibiity.asObservable().observeOn(MainScheduler())
    }

    public func observeErrorMessageVisibiity() -> Observable<Double> {
        return errorMessageVisibiity.asObservable().observeOn(MainScheduler())
    }

    public func observeErrorMessageLabel() -> Observable<String> {
        return errorMessageLabel.asObservable().observeOn(MainScheduler())
    }
}

class ViewController {
    let viewModel = ViewModel()
    let disposeBag = DisposeBag()
    func observeViewModelChanges() {
        viewModel
            .observeProgressBarVisibiity()
            .subscribe(onNext: { value in
                self.progressBar.hide = viewModel.getProgressBarVisibility()
            })
            .disposed(by: disposeBag)

        viewModel
            .observeErrorMessageVisibiity()
            .subscribe(onNext: { value in
                self.errorMessageLabel.hide = value
            })
            .disposed(by: disposeBag)

        viewModel
            .observeErrorMessageLabel()
            .subscribe(onNext: { value in
                self.errorMessageLabel.text = value
            })
            .disposed(by: disposeBag)
    }
}

推荐阅读