Improve TouchableOpacity

Summary:
I was comparing `<TouchableOpacity>` to `UIButton` in iOS and it just doesn't feel native. The initial delay was fixed by https://github.com/facebook/react-native/pull/10866 but still there is a lag between button release and animation.

I'm also not sure what `_hideTimeout` was used for. When logging `touchableHandle*` events looks like `touchableHandleActivePressIn` is called first, then `touchableHandleActivePressOut` and then `touchableHandlePress`. Which means the fade in animation from `touchableHandleActivePressOut` was interrupted by `touchableHandlePress`.

Reviewed By: vjeux

Differential Revision: D4309789

fbshipit-source-id: b6d4df544952e11c2ade97d860531cbb2fada36b
This commit is contained in:
Alex Kotliarskyi 2016-12-13 11:21:48 -08:00 committed by Facebook Github Bot
parent 194604f0a1
commit 41f2169629
1 changed files with 11 additions and 17 deletions

View File

@ -14,6 +14,7 @@
// Note (avik): add @flow when Flow supports spread properties in propTypes // Note (avik): add @flow when Flow supports spread properties in propTypes
var Animated = require('Animated'); var Animated = require('Animated');
var Easing = require('Easing');
var NativeMethodsMixin = require('NativeMethodsMixin'); var NativeMethodsMixin = require('NativeMethodsMixin');
var React = require('React'); var React = require('React');
var TimerMixin = require('react-timer-mixin'); var TimerMixin = require('react-timer-mixin');
@ -84,10 +85,15 @@ var TouchableOpacity = React.createClass({
/** /**
* Animate the touchable to a new opacity. * Animate the touchable to a new opacity.
*/ */
setOpacityTo: function(value: number, duration: number = 150) { setOpacityTo: function(value: number, duration: number) {
Animated.timing( Animated.timing(
this.state.anim, this.state.anim,
{toValue: value, duration: duration, useNativeDriver: true} {
toValue: value,
duration: duration,
easing: Easing.inOut(Easing.quad),
useNativeDriver: true,
}
).start(); ).start();
}, },
@ -96,8 +102,6 @@ var TouchableOpacity = React.createClass({
* defined on your component. * defined on your component.
*/ */
touchableHandleActivePressIn: function(e: Event) { touchableHandleActivePressIn: function(e: Event) {
this.clearTimeout(this._hideTimeout);
this._hideTimeout = null;
if (e.dispatchConfig.registrationName === 'onResponderGrant') { if (e.dispatchConfig.registrationName === 'onResponderGrant') {
this._opacityActive(0); this._opacityActive(0);
} else { } else {
@ -107,19 +111,11 @@ var TouchableOpacity = React.createClass({
}, },
touchableHandleActivePressOut: function(e: Event) { touchableHandleActivePressOut: function(e: Event) {
if (!this._hideTimeout) { this._opacityInactive(250);
this._opacityInactive();
}
this.props.onPressOut && this.props.onPressOut(e); this.props.onPressOut && this.props.onPressOut(e);
}, },
touchableHandlePress: function(e: Event) { touchableHandlePress: function(e: Event) {
this.clearTimeout(this._hideTimeout);
this._opacityActive(150);
this._hideTimeout = this.setTimeout(
this._opacityInactive,
this.props.delayPressOut || 100
);
this.props.onPress && this.props.onPress(e); this.props.onPress && this.props.onPress(e);
}, },
@ -152,13 +148,11 @@ var TouchableOpacity = React.createClass({
this.setOpacityTo(this.props.activeOpacity, duration); this.setOpacityTo(this.props.activeOpacity, duration);
}, },
_opacityInactive: function() { _opacityInactive: function(duration: number) {
this.clearTimeout(this._hideTimeout);
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 duration
); );
}, },