예시) whiteSlider.rx.value는 controlProperty로 옵저버, 옵저버블 모두 가능함.
→ Binder : Write Only (Observer)
→ ControlProperty : Read/Write 모두 가 능)(Observer, Observable)모두 가능함.
@IBOutlet weak var resetButton: UIBarButtonItem!
@IBOutlet weak var whiteSlider: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
//Observable로 동작함.
whiteSlider.rx.value
.map { value in
print(value)
return UIColor(white: CGFloat(value), alpha: 1.0)
}
.bind(to: view.rx.backgroundColor)
.disposed(by: bag)
//Observer로 동작함
resetButton.rx.tap
.map { Float(0.5) }
.bind(to: whiteSlider.rx.value)
.disposed(by: bag)
var color: ControlProperty<UIColor?>{
return base.rx.controlProperty(editingEvents: .valueChanged) { slider in
return UIColor(white: CGFloat(slider.value), alpha: 1.0)
} setter: { slider, color in
var white = CGFloat(1)
color?.getWhite(&white, alpha: nil)
slider.value = Float(white)
}
}
/// Creates a `ControlProperty` that is triggered by target/action pattern value updates.
///
/// - parameter controlEvents: Events that trigger value update sequence elements.
/// - parameter getter: Property value getter.
/// - parameter setter: Property value setter.
public func controlProperty<T>(
editingEvents: UIControl.Event,
getter: @escaping (Base) -> T,
setter: @escaping (Base, T) -> Void
) -> ControlProperty<T> {
let source: Observable<T> = Observable.create { [weak weakControl = base] observer in
guard let control = weakControl else {
observer.on(.completed)
return Disposables.create()
}
observer.on(.next(getter(control)))
let controlTarget = ControlTarget(control: control, controlEvents: editingEvents) { _ in
if let control = weakControl {
observer.on(.next(getter(control)))
}
}
return Disposables.create(with: controlTarget.dispose)
}
.takeUntil(deallocated)
let bindingObserver = Binder(base, binding: setter)
return ControlProperty<T>(values: source, valueSink: bindingObserver)
}
파라메터로 전달받은 UIControl Event가 발생하면 Next이벤트로 getter 메소드가호출됨.
바인딩 되는경우 새로운 바인더 생성