将 rx.value 添加到我的 CustomView

Add a rx.value to my CustomView

假设我有一个 CustomView,里面有一个值。 我想使用 rx.value (Observable) 向世界公开该值,而不是必须按值 (Int) 访问它。

final class CustomView: UIView {
   var value: Int = 0
   ...
}

我从 UIStepper+Rx 复制了这个:

extension Reactive where Base: CustomView {

    var value: ControlProperty<Int> {
        return base.rx.controlProperty(editingEvents: [.allEditingEvents, .valueChanged],
            getter: { customView in
                customView.currentValue
        }, setter: { customView, value in
            customView.currentValue = value
        }
        )
    }

}

final class CustomView: UIControl {

    fileprivate var currentValue = 1 {
        didSet {
            checkButtonState()
            valueLabel.text = currentValue.description
        }
    }

   // inside i set currentValue = 3
}

但是 customView.rx.value 不发出任何值

我认为您想使用主题,可以是 PublishSubject 或变量。

PublishSubject 以空序列开始,只向其订阅者发出新的 Next 事件。变量允许在开始时设置初始值并向订阅者重播最新值或初始值。变量保证不会失败,它不会也不能发出错误。 本教程帮助 https://medium.com/@dkhuong291/rxswift-subjects-part1-publishsubjects-103ff6b06932

因此您需要像这样为您的主题设置值:

 var myValue = PublishSubject<Int>()
 ...
 myValue.onNext(2)

 var myValue = Variable<Int>(0)
 ...
 myValue.value = 2

那就订阅吧:

var disposeBag = DisposeBag()
myValue.asObservable()
    .subscribe({
        print([=12=])
    }).disposed(by: disposebag) 

此外,您可能只想使用字符串 Subject 将值绑定到您的 UILabel。

var myValue = PublishSubject<String>()
...
myValue.onNext("\(4)")
...
func viewDidLoad() {
     super.viewDidLoad()
     myValue.asObservable().bind(to: valueLabel.text)
}

或者,假设您想通过 rx.value 设置您的值。您需要使用 RxCocoa 创建一个自定义视图的 DelegateProxy class。这与为您的 CustomView 创建一个委托相同,您可以在其中通过在您想要的任何地方设置它们的值来委托您的属性,并通过 customView.rx...

收听它们

我上个月在此发布了一些内容 。 它确实帮助我轻松控制自定义视图属性。

缺少的是,您需要在 UIControl 上发送操作。检查下一个示例:

class CustomView: UIControl {
    var value: Int = 0 {
        didSet { sendActions(for: .valueChanged) } // You are missing this part
    }
}

extension Reactive where Base: CustomView {

    var value: ControlProperty<Int> {
        return base.rx.controlProperty(editingEvents: UIControlEvents.valueChanged,
                                       getter: { customView in
                                        return customView.value },
                                       setter: { (customView, newValue) in
                                        customView.value = newValue})
    }

}