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