1010#import < react/components/slider/SliderEventEmitter.h>
1111#import < react/components/slider/SliderProps.h>
1212#import < react/components/slider/SliderShadowNode.h>
13+ #import < react/components/slider/SliderLocalData.h>
14+ #import < React/RCTImageResponseObserverProxy.h>
15+
16+ #import " MainQueueExecutor.h"
1317
1418using namespace facebook ::react;
1519
1620@implementation RCTSliderComponentView {
1721 UISlider *_sliderView;
18- float _prevValue;
22+ float _previousValue;
23+ SharedSliderLocalData _sliderLocalData;
24+
25+ UIImage *_trackImage;
26+ UIImage *_minimumTrackImage;
27+ UIImage *_maximumTrackImage;
28+ UIImage *_thumbImage;
29+
30+ std::shared_ptr<const ImageResponseObserverCoordinator> _trackImageCoordinator;
31+ std::unique_ptr<RCTImageResponseObserverProxy> _trackImageResponseObserverProxy;
32+ std::shared_ptr<const ImageResponseObserverCoordinator> _minimumTrackImageCoordinator;
33+ std::unique_ptr<RCTImageResponseObserverProxy> _minimumTrackImageResponseObserverProxy;
34+ std::shared_ptr<const ImageResponseObserverCoordinator> _maximumTrackImageCoordinator;
35+ std::unique_ptr<RCTImageResponseObserverProxy> _maximumTrackImageResponseObserverProxy;
36+ std::shared_ptr<const ImageResponseObserverCoordinator> _thumbImageCoordinator;
37+ std::unique_ptr<RCTImageResponseObserverProxy> _thumbImageResponseObserverProxy;
1938}
2039
2140- (instancetype )initWithFrame : (CGRect)frame
@@ -29,9 +48,19 @@ - (instancetype)initWithFrame:(CGRect)frame
2948 [_sliderView addTarget: self
3049 action: @selector (onChange: )
3150 forControlEvents: UIControlEventValueChanged];
51+ [_sliderView addTarget: self
52+ action: @selector (sliderTouchEnd: )
53+ forControlEvents: (UIControlEventTouchUpInside |
54+ UIControlEventTouchUpOutside |
55+ UIControlEventTouchCancel)];
3256
3357 _sliderView.value = defaultProps->value ;
3458
59+ _trackImageResponseObserverProxy = std::make_unique<RCTImageResponseObserverProxy>((__bridge void *)self);
60+ _minimumTrackImageResponseObserverProxy = std::make_unique<RCTImageResponseObserverProxy>((__bridge void *)self);
61+ _maximumTrackImageResponseObserverProxy = std::make_unique<RCTImageResponseObserverProxy>((__bridge void *)self);
62+ _thumbImageResponseObserverProxy = std::make_unique<RCTImageResponseObserverProxy>((__bridge void *)self);
63+
3564 self.contentView = _sliderView;
3665 }
3766
@@ -55,7 +84,17 @@ - (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps
5584 // `value`
5685 if (oldSliderProps.value != newSliderProps.value ) {
5786 _sliderView.value = newSliderProps.value ;
58- _prevValue = newSliderProps.value ;
87+ _previousValue = newSliderProps.value ;
88+ }
89+
90+ // `minimumValue`
91+ if (oldSliderProps.minimumValue != newSliderProps.minimumValue ) {
92+ _sliderView.minimumValue = newSliderProps.minimumValue ;
93+ }
94+
95+ // `maximumValue`
96+ if (oldSliderProps.maximumValue != newSliderProps.maximumValue ) {
97+ _sliderView.maximumValue = newSliderProps.maximumValue ;
5998 }
6099
61100 // `disabled`
@@ -79,14 +118,178 @@ - (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps
79118 }
80119}
81120
82- - (void )onChange : (UISlider *)sender
121+ - (void )updateLocalData : (SharedLocalData)localData
122+ oldLocalData : (SharedLocalData)oldLocalData
83123{
84- if (_prevValue == sender.value ) {
124+ SharedSliderLocalData previousData = _sliderLocalData;
125+ _sliderLocalData = std::static_pointer_cast<const SliderLocalData>(localData);
126+ assert (_sliderLocalData);
127+ bool havePreviousData = previousData != nullptr ;
128+
129+ if (!havePreviousData || _sliderLocalData->getTrackImageSource () != previousData->getTrackImageSource ()) {
130+ self.trackImageCoordinator = _sliderLocalData->getTrackImageRequest ().getObserverCoordinator ();
131+ }
132+ if (!havePreviousData || _sliderLocalData->getMinimumTrackImageSource () != previousData->getMinimumTrackImageSource ()) {
133+ self.minimumTrackImageCoordinator = _sliderLocalData->getMinimumTrackImageRequest ().getObserverCoordinator ();
134+ }
135+ if (!havePreviousData || _sliderLocalData->getMaximumTrackImageSource () != previousData->getMaximumTrackImageSource ()) {
136+ self.maximumTrackImageCoordinator = _sliderLocalData->getMaximumTrackImageRequest ().getObserverCoordinator ();
137+ }
138+ if (!havePreviousData || _sliderLocalData->getThumbImageSource () != previousData->getThumbImageSource ()) {
139+ self.thumbImageCoordinator = _sliderLocalData->getThumbImageRequest ().getObserverCoordinator ();
140+ }
141+ }
142+
143+ - (void )setTrackImageCoordinator : (std::shared_ptr<const ImageResponseObserverCoordinator>)coordinator {
144+ if (_trackImageCoordinator) {
145+ _trackImageCoordinator->removeObserver (_trackImageResponseObserverProxy.get ());
146+ }
147+ _trackImageCoordinator = coordinator;
148+ if (_trackImageCoordinator != nullptr ) {
149+ _trackImageCoordinator->addObserver (_trackImageResponseObserverProxy.get ());
150+ }
151+ }
152+
153+ - (void )setMinimumTrackImageCoordinator : (std::shared_ptr<const ImageResponseObserverCoordinator>)coordinator {
154+ if (_minimumTrackImageCoordinator) {
155+ _minimumTrackImageCoordinator->removeObserver (_minimumTrackImageResponseObserverProxy.get ());
156+ }
157+ _minimumTrackImageCoordinator = coordinator;
158+ if (_minimumTrackImageCoordinator != nullptr ) {
159+ _minimumTrackImageCoordinator->addObserver (_minimumTrackImageResponseObserverProxy.get ());
160+ }
161+ }
162+
163+ - (void )setMaximumTrackImageCoordinator : (std::shared_ptr<const ImageResponseObserverCoordinator>)coordinator {
164+ if (_maximumTrackImageCoordinator) {
165+ _maximumTrackImageCoordinator->removeObserver (_maximumTrackImageResponseObserverProxy.get ());
166+ }
167+ _maximumTrackImageCoordinator = coordinator;
168+ if (_maximumTrackImageCoordinator != nullptr ) {
169+ _maximumTrackImageCoordinator->addObserver (_maximumTrackImageResponseObserverProxy.get ());
170+ }
171+ }
172+
173+ - (void )setThumbImageCoordinator : (std::shared_ptr<const ImageResponseObserverCoordinator>)coordinator {
174+ if (_thumbImageCoordinator) {
175+ _thumbImageCoordinator->removeObserver (_thumbImageResponseObserverProxy.get ());
176+ }
177+ _thumbImageCoordinator = coordinator;
178+ if (_thumbImageCoordinator != nullptr ) {
179+ _thumbImageCoordinator->addObserver (_thumbImageResponseObserverProxy.get ());
180+ }
181+ }
182+
183+ - (void )setTrackImage : (UIImage *)trackImage {
184+ if ([trackImage isEqual: _trackImage]) {
185+ return ;
186+ }
187+
188+ _trackImage = trackImage;
189+ _minimumTrackImage = nil ;
190+ _maximumTrackImage = nil ;
191+ CGFloat width = trackImage.size .width / 2 ;
192+ UIImage *minimumTrackImage = [trackImage resizableImageWithCapInsets: (UIEdgeInsets){
193+ 0 , width, 0 , width
194+ } resizingMode: UIImageResizingModeStretch];
195+ UIImage *maximumTrackImage = [trackImage resizableImageWithCapInsets: (UIEdgeInsets){
196+ 0 , width, 0 , width
197+ } resizingMode: UIImageResizingModeStretch];
198+ [_sliderView setMinimumTrackImage: minimumTrackImage forState: UIControlStateNormal];
199+ [_sliderView setMaximumTrackImage: maximumTrackImage forState: UIControlStateNormal];
200+ }
201+
202+ -(void )setMinimumTrackImage : (UIImage *)minimumTrackImage {
203+ if ([minimumTrackImage isEqual: _minimumTrackImage] && _trackImage == nil ) {
85204 return ;
86205 }
87- _prevValue = sender.value ;
206+
207+ _trackImage = nil ;
208+ _minimumTrackImage = minimumTrackImage;
209+ _minimumTrackImage = [_minimumTrackImage resizableImageWithCapInsets: (UIEdgeInsets) {
210+ 0 , _minimumTrackImage.size .width , 0 , 0
211+ } resizingMode: UIImageResizingModeStretch];
212+ [_sliderView setMinimumTrackImage: _minimumTrackImage forState: UIControlStateNormal];
213+ }
88214
89- std::dynamic_pointer_cast<const SliderEventEmitter>(_eventEmitter)->onValueChange (sender.value );
215+ -(void )setMaximumTrackImage : (UIImage *)maximumTrackImage {
216+ if ([maximumTrackImage isEqual: _maximumTrackImage] && _trackImage == nil ) {
217+ return ;
218+ }
219+
220+ _trackImage = nil ;
221+ _maximumTrackImage = maximumTrackImage;
222+ _maximumTrackImage = [_maximumTrackImage resizableImageWithCapInsets: (UIEdgeInsets) {
223+ 0 , 0 , 0 , _maximumTrackImage.size .width
224+ } resizingMode: UIImageResizingModeStretch];
225+ [_sliderView setMaximumTrackImage: _maximumTrackImage forState: UIControlStateNormal];
90226}
91227
228+ -(void )setThumbImage : (UIImage *)thumbImage {
229+ if ([thumbImage isEqual: _thumbImage]) {
230+ return ;
231+ }
232+
233+ _thumbImage = thumbImage;
234+ [_sliderView setThumbImage: thumbImage forState: UIControlStateNormal];
235+ }
236+
237+ - (void )onChange : (UISlider *)sender
238+ {
239+ [self onChange: sender withContinuous: YES ];
240+ }
241+
242+ - (void )sliderTouchEnd : (UISlider *)sender
243+ {
244+ [self onChange: sender withContinuous: NO ];
245+ }
246+
247+ - (void )onChange : (UISlider *)sender withContinuous : (BOOL )continuous
248+ {
249+ float value = sender.value ;
250+
251+ const auto &props = *std::static_pointer_cast<const SliderProps>(_props);
252+
253+ if (props.step > 0 && value <= (props.maximumValue - props.minimumValue )) {
254+ value = MAX (props.minimumValue ,
255+ MIN (props.maximumValue ,
256+ props.minimumValue + round ((value - props.minimumValue ) / props.step ) * props.step
257+ )
258+ );
259+
260+ [_sliderView setValue: value animated: YES ];
261+ }
262+
263+ if (continuous && _previousValue != value) {
264+ std::dynamic_pointer_cast<const SliderEventEmitter>(_eventEmitter)->onValueChange (value);
265+ }
266+ if (!continuous) {
267+ std::dynamic_pointer_cast<const SliderEventEmitter>(_eventEmitter)->onSlidingComplete (value);
268+ }
269+
270+ _previousValue = value;
271+ }
272+
273+ #pragma mark - RCTImageResponseDelegate
274+
275+ - (void )didReceiveImage : (UIImage *)image fromObserver : (void *)observer
276+ {
277+ if (observer == _trackImageResponseObserverProxy.get ()) {
278+ self.trackImage = image;
279+ } else if (observer == _minimumTrackImageResponseObserverProxy.get ()) {
280+ self.minimumTrackImage = image;
281+ } else if (observer == _maximumTrackImageResponseObserverProxy.get ()) {
282+ self.maximumTrackImage = image;
283+ } else if (observer == _thumbImageResponseObserverProxy.get ()) {
284+ self.thumbImage = image;
285+ }
286+ }
287+
288+ - (void )didReceiveProgress : (float )progress fromObserver : (void *)observer {
289+ }
290+
291+ - (void )didReceiveFailureFromObserver : (void *)observer {
292+ }
293+
294+
92295@end
0 commit comments