[SliderIOS] Apply value after minimum/maximumValue in order to ensure it is properly set

Summary:
`value` is clamped between min/max and so order of prop application matters - `value` always ended up being set first in my tests, and consequently a value outside of the default range 0-1 would not work. So this applies the value when the min/max are set.

[Gist of broken example](https://gist.github.com/brentvatne/fc637b3e21d012966f3a)

![screenshot](http://url.brentvatne.ca/SQPC.png)
^ the second slider here should have it's cursor in the middle

/cc @tadeuzagallo
Closes https://github.com/facebook/react-native/pull/835
Github Author: Brent Vatne <brent.vatne@madriska.com>

Test Plan: Imported from GitHub, without a `Test Plan:` line.
This commit is contained in:
Brent Vatne 2015-04-21 10:50:10 -07:00
parent 173615ae26
commit 5fb5148e3d
3 changed files with 59 additions and 10 deletions

14
React/Views/RCTSlider.h Normal file
View File

@ -0,0 +1,14 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import <UIKit/UIKit.h>
@interface RCTSlider : UISlider
@end

35
React/Views/RCTSlider.m Normal file
View File

@ -0,0 +1,35 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "RCTSlider.h"
@implementation RCTSlider
{
float _unclippedValue;
}
- (void)setValue:(float)value
{
_unclippedValue = value;
super.value = value;
}
- (void)setMinimumValue:(float)minimumValue
{
super.minimumValue = minimumValue;
super.value = _unclippedValue;
}
- (void)setMaximumValue:(float)maximumValue
{
super.maximumValue = maximumValue;
super.value = _unclippedValue;
}
@end

View File

@ -11,6 +11,7 @@
#import "RCTBridge.h" #import "RCTBridge.h"
#import "RCTEventDispatcher.h" #import "RCTEventDispatcher.h"
#import "RCTSlider.h"
#import "UIView+React.h" #import "UIView+React.h"
@implementation RCTSliderManager @implementation RCTSliderManager
@ -19,32 +20,31 @@ RCT_EXPORT_MODULE()
- (UIView *)view - (UIView *)view
{ {
UISlider *slider = [[UISlider alloc] init]; RCTSlider *slider = [[RCTSlider alloc] init];
[slider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged]; [slider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
[slider addTarget:self action:@selector(sliderTouchEnd:) forControlEvents:UIControlEventTouchUpInside]; [slider addTarget:self action:@selector(sliderTouchEnd:) forControlEvents:UIControlEventTouchUpInside];
return slider; return slider;
} }
- (void)sliderValueChanged:(UISlider *)sender static void RCTSendSliderEvent(RCTSliderManager *self, UISlider *sender, BOOL continuous)
{ {
NSDictionary *event = @{ NSDictionary *event = @{
@"target": sender.reactTag, @"target": sender.reactTag,
@"value": @(sender.value), @"value": @(sender.value),
@"continuous": @YES, @"continuous": @(continuous),
}; };
[self.bridge.eventDispatcher sendInputEventWithName:@"topChange" body:event]; [self.bridge.eventDispatcher sendInputEventWithName:@"topChange" body:event];
} }
- (void)sliderValueChanged:(UISlider *)sender
{
RCTSendSliderEvent(self, sender, YES);
}
- (void)sliderTouchEnd:(UISlider *)sender - (void)sliderTouchEnd:(UISlider *)sender
{ {
NSDictionary *event = @{ RCTSendSliderEvent(self, sender, NO);
@"target": sender.reactTag,
@"value": @(sender.value),
@"continuous": @NO,
};
[self.bridge.eventDispatcher sendInputEventWithName:@"topChange" body:event];
} }
RCT_EXPORT_VIEW_PROPERTY(value, float); RCT_EXPORT_VIEW_PROPERTY(value, float);