RxSwift与BehaviorRelay <any?>

时间:2018-08-07 08:46:56

标签: swift binding rx-swift

我创建一个通用变量。例如,此变量可以连接到textField或其他接口元素,如开关。因此,变量的类型将为Any,以便我可以存储布尔值,字符串或其他内容。

var test: BehaviorRelay<Any?> = BehaviorRelay<Any?>(value: nil)

然后我尝试将接口元素连接到此变量

(self.switch.rx.value <-> viewModel.test).disposed(by: self.disposeBag)

(self.textfield.rx.text <-> viewModel.test).disposed(by: self.disposeBag)

出现此错误Cannot convert value of type 'BehaviorRelay<Any?>' to expected argument type 'BehaviorRelay<Bool>'Cannot convert value of type 'BehaviorRelay<Any?>' to expected argument type 'BehaviorRelay<String?>'

如何使用RxSwift做到这一点?

您可以在这里找到我的<->函数:

infix operator <->
func <-> <T>(property: ControlProperty<T>, variable: BehaviorRelay<T>) -> Disposable {        
    let bindToUIDisposable = variable.asObservable()
        .bind(to: property)
    let bindToVariable = property
        .subscribe(onNext: { n in
            variable.accept(n)
        }, onCompleted:  {
            bindToUIDisposable.dispose()
        })

    return Disposables.create(bindToUIDisposable, bindToVariable)
}

1 个答案:

答案 0 :(得分:2)

(双向绑定在这种情况下不会引起无限循环,因为UI元素在以编程方式进行修改时不会发出值,而是仅在用户更改值时才发出值。如果用户按下开关,它将被推送到Subject [BehaviorRelay],然后再将值推送回开关,但到此为止。)

您将必须使用map将Element转换为Any?并映射Any?从BehaviorRelay转到UI元素时,返回正确的类型。这样做很笨拙而且不安全。

最好是将BehaviorRelay的元素设置为正确的类型。无论如何,您都必须知道该类型,以进行有用的操作。