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
This commit is contained in:
Nick Lockwood 2015-10-30 09:12:10 -07:00 committed by facebook-github-bot-3
parent 2fa58b58f9
commit 0d14d0f1ce
4 changed files with 67 additions and 41 deletions

View File

@ -37,7 +37,7 @@ var SliderExample = React.createClass({
{this.state.value}
</Text>
<SliderIOS
style={styles.slider}
{...this.props}
onValueChange={(value) => this.setState({value: value})} />
</View>
);
@ -62,7 +62,26 @@ exports.displayName = 'SliderExample';
exports.description = 'Slider input for numeric values';
exports.examples = [
{
title: 'SliderIOS',
render(): ReactElement { return <SliderExample />; }
title: 'Default settings',
render(): ReactElement {
return <SliderExample />;
}
},
{
title: 'minimumValue: -1, maximumValue: 2',
render(): ReactElement {
return (
<SliderExample
minimumValue={-1}
maximumValue={2}
/>
);
}
},
{
title: 'step: 0.25',
render(): ReactElement {
return <SliderExample step={0.25} />;
}
}
];

View File

@ -88,17 +88,6 @@ var SliderIOS = React.createClass({
onSlidingComplete: PropTypes.func,
},
_onValueChange: function(event: Event) {
this.props.onChange && this.props.onChange(event);
if (event.nativeEvent.continuous) {
this.props.onValueChange &&
this.props.onValueChange(event.nativeEvent.value);
} else {
this.props.onSlidingComplete && event.nativeEvent.value !== undefined &&
this.props.onSlidingComplete(event.nativeEvent.value);
}
},
getDefaultProps: function() : any {
return {
disabled: false,
@ -106,17 +95,26 @@ var SliderIOS = React.createClass({
},
render: function() {
let onValueChange = this.props.onValueChange && ((event: Event) => {
this.props.onValueChange &&
this.props.onValueChange(event.nativeEvent.value);
});
let onSlidingComplete = this.props.onSlidingComplete && ((event: Event) => {
this.props.onSlidingComplete &&
this.props.onSlidingComplete(event.nativeEvent.value);
});
let {style, ...props} = this.props;
style = [styles.slider, this.props.style];
return (
<RCTSlider
style={[styles.slider, this.props.style]}
value={this.props.value}
step={this.props.step}
maximumValue={this.props.maximumValue}
minimumValue={this.props.minimumValue}
minimumTrackTintColor={this.props.minimumTrackTintColor}
maximumTrackTintColor={this.props.maximumTrackTintColor}
disabled={this.props.disabled}
onChange={this._onValueChange}
{...props}
style={style}
onValueChange={onValueChange}
onSlidingComplete={onSlidingComplete}
/>
);
}
@ -128,8 +126,6 @@ var styles = StyleSheet.create({
},
});
var RCTSlider = requireNativeComponent('RCTSlider', SliderIOS, {
nativeOnly: { onChange: true },
});
var RCTSlider = requireNativeComponent('RCTSlider', SliderIOS);
module.exports = SliderIOS;

View File

@ -13,7 +13,9 @@
@interface RCTSlider : UISlider
@property (nonatomic, copy) RCTBubblingEventBlock onChange;
@property (nonatomic, copy) RCTBubblingEventBlock onValueChange;
@property (nonatomic, copy) RCTBubblingEventBlock onSlidingComplete;
@property (nonatomic, assign) float step;
@property (nonatomic, assign) float lastValue;

View File

@ -21,10 +21,12 @@ RCT_EXPORT_MODULE()
- (UIView *)view
{
RCTSlider *slider = [RCTSlider new];
[slider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
[slider addTarget:self action:@selector(sliderTouchEnd:) forControlEvents:(UIControlEventTouchUpInside |
UIControlEventTouchUpOutside |
UIControlEventTouchCancel)];
[slider addTarget:self action:@selector(sliderValueChanged:)
forControlEvents:UIControlEventValueChanged];
[slider addTarget:self action:@selector(sliderTouchEnd:)
forControlEvents:(UIControlEventTouchUpInside |
UIControlEventTouchUpOutside |
UIControlEventTouchCancel)];
return slider;
}
@ -34,23 +36,29 @@ static void RCTSendSliderEvent(RCTSlider *sender, BOOL continuous)
if (sender.step > 0 &&
sender.step <= (sender.maximumValue - sender.minimumValue)) {
value =
MAX(sender.minimumValue,
MIN(sender.maximumValue,
sender.minimumValue + round((sender.value - sender.minimumValue) / sender.step) * sender.step
)
);
[sender setValue:value animated:YES];
}
if (!continuous) {
sender.value = value;
}
if (sender.onChange && (sender.lastValue != value || !continuous)) {
sender.onChange(@{
@"value": @(value),
@"continuous": @(continuous),
});
if (continuous) {
if (sender.onValueChange && sender.lastValue != value) {
sender.onValueChange(@{
@"value": @(value),
});
}
} else {
if (sender.onSlidingComplete) {
sender.onSlidingComplete(@{
@"value": @(value),
});
}
}
sender.lastValue = value;
@ -72,7 +80,8 @@ RCT_EXPORT_VIEW_PROPERTY(minimumValue, float);
RCT_EXPORT_VIEW_PROPERTY(maximumValue, float);
RCT_EXPORT_VIEW_PROPERTY(minimumTrackTintColor, UIColor);
RCT_EXPORT_VIEW_PROPERTY(maximumTrackTintColor, UIColor);
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onValueChange, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onSlidingComplete, RCTBubblingEventBlock);
RCT_CUSTOM_VIEW_PROPERTY(disabled, BOOL, RCTSlider)
{
if (json) {