Skip to content

Commit

Permalink
TouchableOpacity: Respond instantly to first touch
Browse files Browse the repository at this point in the history
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
ariabuckles authored and Facebook Github Bot committed Nov 14, 2016
1 parent be5e300 commit fa8c536
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
5 changes: 4 additions & 1 deletion Libraries/Animated/src/AnimatedImplementation.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -302,7 +302,10 @@ class TimingAnimation extends Animation {
this.__onEnd = onEnd; this.__onEnd = onEnd;


var start = () => { 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._onUpdate(this._toValue);
this.__debouncedOnEnd({finished: true}); this.__debouncedOnEnd({finished: true});
} else { } else {
Expand Down
19 changes: 12 additions & 7 deletions Libraries/Components/Touchable/TouchableOpacity.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ var TouchableOpacity = React.createClass({
/** /**
* Animate the touchable to a new opacity. * Animate the touchable to a new opacity.
*/ */
setOpacityTo: function(value: number) { setOpacityTo: function(value: number, duration: number = 150) {
Animated.timing( Animated.timing(
this.state.anim, this.state.anim,
{toValue: value, duration: 150, useNativeDriver: true} {toValue: value, duration: duration, useNativeDriver: true}
).start(); ).start();
}, },


Expand All @@ -98,7 +98,11 @@ var TouchableOpacity = React.createClass({
touchableHandleActivePressIn: function(e: Event) { touchableHandleActivePressIn: function(e: Event) {
this.clearTimeout(this._hideTimeout); this.clearTimeout(this._hideTimeout);
this._hideTimeout = null; this._hideTimeout = null;
this._opacityActive(); if (e.dispatchConfig.registrationName === 'onResponderGrant') {
this._opacityActive(0);
} else {
this._opacityActive(150);
}
this.props.onPressIn && this.props.onPressIn(e); this.props.onPressIn && this.props.onPressIn(e);
}, },


Expand All @@ -111,7 +115,7 @@ var TouchableOpacity = React.createClass({


touchableHandlePress: function(e: Event) { touchableHandlePress: function(e: Event) {
this.clearTimeout(this._hideTimeout); this.clearTimeout(this._hideTimeout);
this._opacityActive(); this._opacityActive(150);
this._hideTimeout = this.setTimeout( this._hideTimeout = this.setTimeout(
this._opacityInactive, this._opacityInactive,
this.props.delayPressOut || 100 this.props.delayPressOut || 100
Expand Down Expand Up @@ -144,16 +148,17 @@ var TouchableOpacity = React.createClass({
return this.props.delayPressOut; return this.props.delayPressOut;
}, },


_opacityActive: function() { _opacityActive: function(duration: number) {
this.setOpacityTo(this.props.activeOpacity); this.setOpacityTo(this.props.activeOpacity, duration);
}, },


_opacityInactive: function() { _opacityInactive: function() {
this.clearTimeout(this._hideTimeout); this.clearTimeout(this._hideTimeout);
this._hideTimeout = null; this._hideTimeout = null;
var childStyle = flattenStyle(this.props.style) || {}; var childStyle = flattenStyle(this.props.style) || {};
this.setOpacityTo( this.setOpacityTo(
childStyle.opacity === undefined ? 1 : childStyle.opacity childStyle.opacity === undefined ? 1 : childStyle.opacity,
150
); );
}, },


Expand Down

0 comments on commit fa8c536

Please sign in to comment.