UIControl의 사용자 정의 서브 클래스를 작성 중입니다. (그 draw 메소드를 재정의해야합니다.) isSelected 특성을 내 모델에 바인드하기 위해 RxSwift를 추가하고 싶습니다.RxSwift가있는 사용자 정의 UIControl 서브 클래스
지금까지 그렇게 좋았습니다. 이것은 잘 작동합니다.
내 문제는 사용자 touchUpInside 이벤트에 응답하여 isSelected 속성을 변경하는 방법입니다.
내 첫 번째 시도는 UIControl의 addTarget을 방법을 사용했지만, (해당 문서에 명시된) 프로그래밍 ControlProperty에 의해보고되지 않습니다 에 isSelected의 값을 변경. 그러나 나는 이것을 해결할 다른 방법을 생각할 수있다.
도움을 주시면 감사하겠습니다. 서브 클래스의
소스 코드 :
class SYYesNoButton: UIControl {
override init(frame: CGRect) {
super.init(frame: frame)
// subscribe to touchUpInside event
addTarget(
self,
action: #selector(userDidTouchUpInside),
for: UIControlEvents.touchUpInside)
}
func userDidTouchUpInside() {
// change the value of the property
// this does not work,
// the change is not reported to the ControlProperty
// HOW CAN I CHANGE THIS ??
self.isSelected = !isSelected
}
}
확장
반응성 지원을 추가 : 모든extension SYYesNoButton {
var rx_isSelected: ControlProperty<Bool> {
return UIControl.valuePublic(
self,
getter: { (button) -> Bool in
return button.isSelected
},
setter: { (button, value) in
button.isSelected = value
})
}
}
extension UIControl {
static func valuePublic<T, ControlType: UIControl>(_ control: ControlType, getter: @escaping (ControlType) -> T, setter: @escaping (ControlType, T) ->()) -> ControlProperty<T> {
let values: Observable<T> = Observable.deferred { [weak control] in
guard let existingSelf = control else {
return Observable.empty()
}
return (existingSelf as UIControl).rx.controlEvent([.allEditingEvents, .valueChanged])
.flatMap { _ in
return control.map { Observable.just(getter($0)) } ?? Observable.empty()
}
.startWith(getter(existingSelf))
}
return ControlProperty(values: values, valueSink: UIBindingObserver(UIElement: control) { control, value in
setter(control, value)
})
}
}
감사합니다. 당신이 UIControl로부터 서브 클래스 화하는 경우
당신은 또한'RxCocoa'을 사용하고 있습니까? – ozgur
RxCocoa도 사용합니다. – t4ncr3d3