I have a UISlider which shows playback progress through a song and allows seeking within the song. Using RAC it's very easy to obtain a two-way binding between a UISlider's value and a viewModel's value:
RACChannelTo(self, slider.value) = RACChannelTo(viewModel, progress);
However problems arise while the user is interacting with the slider:
I've tried the [slider rac_newValueChannelWithNilValue:@0]
approach with same results. My current solution works, but is shamefully complex:
// Sadly the rac_signalForControlEvents doesn't send the event that triggered it so two signals are needed
RACSignal *touchDown = [self.slider rac_signalForControlEvents:UIControlEventTouchDown];
RACSignal *touchUp = [self.slider rac_signalForControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
RACSignal *isTouched = [[[touchDown map:^id(id value) {
return @(YES);
}] merge:[touchUp map:^id(id value) {
return @(NO);
}]] startWith:@(NO)]; // Needs a startWith because combineLatestWith doesn't send signals until it has at least one value from each component
[[RACObserve(viewModel, progress) combineLatestWith:isTouched] subscribeNext:^(RACTuple *tuple) {
RACTupleUnpack(NSNumber * progress, NSNumber * isTouched) = tuple;
// Update the slider value only if the user isn't touching it
if (!isTouched.boolValue) {
weakSelf.slider.value = progress.floatValue;
}
}];
// Send the value only when user stops interacting
[[touchUp map:^id(UISlider *slider) {
return @(slider.value);
}] subscribeNext:^(id x) {
weakSelf.viewModel.progress = [x floatValue];
}];
Is there a better way of achieving this?
您是否尝试过使用throttle
来减少从滑块发送的值的数量?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.