Permalink
Browse files

TouchableOpacity: Respond instantly to first touch

Summary:
On iOS, when you press down native fading components, they become
transparent instantly, but then have an animated fade in/out if you
move your finger in/out of their hit box.

On react-native currently, the touchdown fades, instead of providing
instant feedback, which doesn't feel right on iOS.

I'm less familiar with Android conventions, but it seems to use fading
components for buttons less often, instead using the ripple effect from
TouchableNativeFeedback. In either case, instant feedback seems better
for the user.
Closes #10866

Differential Revision: D4175854

Pulled By: hramos

fbshipit-source-id: d993231074e8190cf4ba7ca86dc24299f05d5d8f
  • Loading branch information...
1 parent be5e300 commit fa8c536b31cbfec3868bbf36d63c605baa8c0183 @ariabuckles ariabuckles committed with Facebook Github Bot Nov 14, 2016
@@ -302,7 +302,10 @@ class TimingAnimation extends Animation {
this.__onEnd = onEnd;
var start = () => {
- if (this._duration === 0) {
+ // Animations that sometimes have 0 duration and sometimes do not
+ // still need to use the native driver when duration is 0 so as to
+ // not cause intermixed JS and native animations.
+ if (this._duration === 0 && !this._useNativeDriver) {
this._onUpdate(this._toValue);
this.__debouncedOnEnd({finished: true});
} else {
@@ -84,10 +84,10 @@ var TouchableOpacity = React.createClass({
/**
* Animate the touchable to a new opacity.
*/
- setOpacityTo: function(value: number) {
+ setOpacityTo: function(value: number, duration: number = 150) {
Animated.timing(
this.state.anim,
- {toValue: value, duration: 150, useNativeDriver: true}
+ {toValue: value, duration: duration, useNativeDriver: true}
).start();
},
@@ -98,7 +98,11 @@ var TouchableOpacity = React.createClass({
touchableHandleActivePressIn: function(e: Event) {
this.clearTimeout(this._hideTimeout);
this._hideTimeout = null;
- this._opacityActive();
+ if (e.dispatchConfig.registrationName === 'onResponderGrant') {
+ this._opacityActive(0);
+ } else {
+ this._opacityActive(150);
+ }
this.props.onPressIn && this.props.onPressIn(e);
},
@@ -111,7 +115,7 @@ var TouchableOpacity = React.createClass({
touchableHandlePress: function(e: Event) {
this.clearTimeout(this._hideTimeout);
- this._opacityActive();
+ this._opacityActive(150);
this._hideTimeout = this.setTimeout(
this._opacityInactive,
this.props.delayPressOut || 100
@@ -144,16 +148,17 @@ var TouchableOpacity = React.createClass({
return this.props.delayPressOut;
},
- _opacityActive: function() {
- this.setOpacityTo(this.props.activeOpacity);
+ _opacityActive: function(duration: number) {
+ this.setOpacityTo(this.props.activeOpacity, duration);
},
_opacityInactive: function() {
this.clearTimeout(this._hideTimeout);
this._hideTimeout = null;
var childStyle = flattenStyle(this.props.style) || {};
this.setOpacityTo(
- childStyle.opacity === undefined ? 1 : childStyle.opacity
+ childStyle.opacity === undefined ? 1 : childStyle.opacity,
+ 150
);
},

0 comments on commit fa8c536

Please sign in to comment.