Here's something I wrote a while back and reproduced below. If you look at my gist (https://gist.github.com/danielt1263/1a70c4f7b8960d06bd7f1bfa81802cc3) you will see that I originally wrote it as a custom operator. Later I learned that the combination of built in operators below do the same job.
If nothing else, looking back at the older revisions in the gist will give you the sense of how to write your own operators.
extension ObservableType {
/**
Filters the source observable sequence using a trigger observable sequence producing Bool values.
Elements only go through the filter when the trigger has not completed and its last element was true. If either source or trigger error's, then the source errors.
- parameter trigger: Triggering event sequence.
- returns: Filtered observable sequence.
*/
func filter(if trigger: Observable<Bool>) -> Observable<E> {
return withLatestFrom(trigger) { (myValue, triggerValue) -> (Element, Bool) in
return (myValue, triggerValue)
}
.filter { (myValue, triggerValue) -> Bool in
return triggerValue == true
}
.map { (myValue, triggerValue) -> Element in
return myValue
}
}
}
If you want to change what the button does depending on the value of your control observable, setup two filters. Normally the filter only passes through taps when the enableButtons
emits true. Use a map to reverse it in the second case and direct button taps down another path:
button.rx.tap.filter(if: enableButtons)
.subscribe(onNext: { /* do one thing when enableButtons emits true */ }
.disposed(by: bag)
button.rx.tap.filter(if: enableButtons.map { !$0 })
.subscribe(onNext: { /* do other thing when enable buttons emits false*/ }
.disposed(by: bag)
isEnabled
property? This way the buttons won't be able to emit at all – Speciality