Skip to content

Commit 0d14d0f

Browse files
nicklockwoodfacebook-github-bot-3
authored andcommitted
Improved SliderIOS
Summary: public * No longer sends events when not observing valueChanged. * Snaps to step value while dragging. * Added additional example to UIExplorer. Reviewed By: javache Differential Revision: D2595594 fb-gh-sync-id: 1e92427d2ab2e71e4eb4a9a7a75cd0f5f4a3a529
1 parent 2fa58b5 commit 0d14d0f

4 files changed

Lines changed: 66 additions & 40 deletions

File tree

Examples/UIExplorer/SliderIOSExample.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ var SliderExample = React.createClass({
3737
{this.state.value}
3838
</Text>
3939
<SliderIOS
40-
style={styles.slider}
40+
{...this.props}
4141
onValueChange={(value) => this.setState({value: value})} />
4242
</View>
4343
);
@@ -62,7 +62,26 @@ exports.displayName = 'SliderExample';
6262
exports.description = 'Slider input for numeric values';
6363
exports.examples = [
6464
{
65-
title: 'SliderIOS',
66-
render(): ReactElement { return <SliderExample />; }
65+
title: 'Default settings',
66+
render(): ReactElement {
67+
return <SliderExample />;
68+
}
69+
},
70+
{
71+
title: 'minimumValue: -1, maximumValue: 2',
72+
render(): ReactElement {
73+
return (
74+
<SliderExample
75+
minimumValue={-1}
76+
maximumValue={2}
77+
/>
78+
);
79+
}
80+
},
81+
{
82+
title: 'step: 0.25',
83+
render(): ReactElement {
84+
return <SliderExample step={0.25} />;
85+
}
6786
}
6887
];

Libraries/Components/SliderIOS/SliderIOS.ios.js

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -88,35 +88,33 @@ var SliderIOS = React.createClass({
8888
onSlidingComplete: PropTypes.func,
8989
},
9090

91-
_onValueChange: function(event: Event) {
92-
this.props.onChange && this.props.onChange(event);
93-
if (event.nativeEvent.continuous) {
94-
this.props.onValueChange &&
95-
this.props.onValueChange(event.nativeEvent.value);
96-
} else {
97-
this.props.onSlidingComplete && event.nativeEvent.value !== undefined &&
98-
this.props.onSlidingComplete(event.nativeEvent.value);
99-
}
100-
},
101-
10291
getDefaultProps: function() : any {
10392
return {
10493
disabled: false,
10594
};
10695
},
10796

10897
render: function() {
98+
99+
let onValueChange = this.props.onValueChange && ((event: Event) => {
100+
this.props.onValueChange &&
101+
this.props.onValueChange(event.nativeEvent.value);
102+
});
103+
104+
let onSlidingComplete = this.props.onSlidingComplete && ((event: Event) => {
105+
this.props.onSlidingComplete &&
106+
this.props.onSlidingComplete(event.nativeEvent.value);
107+
});
108+
109+
let {style, ...props} = this.props;
110+
style = [styles.slider, this.props.style];
111+
109112
return (
110113
<RCTSlider
111-
style={[styles.slider, this.props.style]}
112-
value={this.props.value}
113-
step={this.props.step}
114-
maximumValue={this.props.maximumValue}
115-
minimumValue={this.props.minimumValue}
116-
minimumTrackTintColor={this.props.minimumTrackTintColor}
117-
maximumTrackTintColor={this.props.maximumTrackTintColor}
118-
disabled={this.props.disabled}
119-
onChange={this._onValueChange}
114+
{...props}
115+
style={style}
116+
onValueChange={onValueChange}
117+
onSlidingComplete={onSlidingComplete}
120118
/>
121119
);
122120
}
@@ -128,8 +126,6 @@ var styles = StyleSheet.create({
128126
},
129127
});
130128

131-
var RCTSlider = requireNativeComponent('RCTSlider', SliderIOS, {
132-
nativeOnly: { onChange: true },
133-
});
129+
var RCTSlider = requireNativeComponent('RCTSlider', SliderIOS);
134130

135131
module.exports = SliderIOS;

React/Views/RCTSlider.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313

1414
@interface RCTSlider : UISlider
1515

16-
@property (nonatomic, copy) RCTBubblingEventBlock onChange;
16+
@property (nonatomic, copy) RCTBubblingEventBlock onValueChange;
17+
@property (nonatomic, copy) RCTBubblingEventBlock onSlidingComplete;
18+
1719
@property (nonatomic, assign) float step;
1820
@property (nonatomic, assign) float lastValue;
1921

React/Views/RCTSliderManager.m

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ @implementation RCTSliderManager
2121
- (UIView *)view
2222
{
2323
RCTSlider *slider = [RCTSlider new];
24-
[slider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
25-
[slider addTarget:self action:@selector(sliderTouchEnd:) forControlEvents:(UIControlEventTouchUpInside |
26-
UIControlEventTouchUpOutside |
27-
UIControlEventTouchCancel)];
24+
[slider addTarget:self action:@selector(sliderValueChanged:)
25+
forControlEvents:UIControlEventValueChanged];
26+
[slider addTarget:self action:@selector(sliderTouchEnd:)
27+
forControlEvents:(UIControlEventTouchUpInside |
28+
UIControlEventTouchUpOutside |
29+
UIControlEventTouchCancel)];
2830
return slider;
2931
}
3032

@@ -34,23 +36,29 @@ static void RCTSendSliderEvent(RCTSlider *sender, BOOL continuous)
3436

3537
if (sender.step > 0 &&
3638
sender.step <= (sender.maximumValue - sender.minimumValue)) {
39+
3740
value =
3841
MAX(sender.minimumValue,
3942
MIN(sender.maximumValue,
4043
sender.minimumValue + round((sender.value - sender.minimumValue) / sender.step) * sender.step
4144
)
4245
);
43-
}
4446

45-
if (!continuous) {
46-
sender.value = value;
47+
[sender setValue:value animated:YES];
4748
}
4849

49-
if (sender.onChange && (sender.lastValue != value || !continuous)) {
50-
sender.onChange(@{
51-
@"value": @(value),
52-
@"continuous": @(continuous),
53-
});
50+
if (continuous) {
51+
if (sender.onValueChange && sender.lastValue != value) {
52+
sender.onValueChange(@{
53+
@"value": @(value),
54+
});
55+
}
56+
} else {
57+
if (sender.onSlidingComplete) {
58+
sender.onSlidingComplete(@{
59+
@"value": @(value),
60+
});
61+
}
5462
}
5563

5664
sender.lastValue = value;
@@ -72,7 +80,8 @@ - (void)sliderTouchEnd:(RCTSlider *)sender
7280
RCT_EXPORT_VIEW_PROPERTY(maximumValue, float);
7381
RCT_EXPORT_VIEW_PROPERTY(minimumTrackTintColor, UIColor);
7482
RCT_EXPORT_VIEW_PROPERTY(maximumTrackTintColor, UIColor);
75-
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock);
83+
RCT_EXPORT_VIEW_PROPERTY(onValueChange, RCTBubblingEventBlock);
84+
RCT_EXPORT_VIEW_PROPERTY(onSlidingComplete, RCTBubblingEventBlock);
7685
RCT_CUSTOM_VIEW_PROPERTY(disabled, BOOL, RCTSlider)
7786
{
7887
if (json) {

0 commit comments

Comments
 (0)