Support inverted gesture in modal
This commit is contained in:
parent
d5be6307f2
commit
4f4b8e4d41
|
@ -22,6 +22,11 @@ class ListScreen extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
class DetailsScreen extends React.Component {
|
class DetailsScreen extends React.Component {
|
||||||
|
static navigationOptions = {
|
||||||
|
// Uncomment below to test inverted modal gesture
|
||||||
|
// gestureDirection: 'inverted',
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
|
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
|
||||||
|
|
|
@ -321,25 +321,26 @@ class StackViewLayout extends React.Component {
|
||||||
_gestureActivationCriteria = () => {
|
_gestureActivationCriteria = () => {
|
||||||
let { layout } = this.props.transitionProps;
|
let { layout } = this.props.transitionProps;
|
||||||
let gestureResponseDistance = this._getGestureResponseDistance();
|
let gestureResponseDistance = this._getGestureResponseDistance();
|
||||||
|
let isMotionInverted = this._isMotionInverted();
|
||||||
|
|
||||||
if (this._isMotionVertical()) {
|
if (this._isMotionVertical()) {
|
||||||
let height = layout.height.__getValue();
|
let height = layout.height.__getValue();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
maxDeltaX: 15,
|
maxDeltaX: 15,
|
||||||
minOffsetY: 5,
|
minOffsetY: isMotionInverted ? -5 : 5,
|
||||||
hitSlop: { bottom: -height + gestureResponseDistance },
|
hitSlop: isMotionInverted
|
||||||
|
? { top: -height + GESTURE_RESPONSE_DISTANCE_VERTICAL }
|
||||||
|
: { bottom: -height + GESTURE_RESPONSE_DISTANCE_VERTICAL },
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
let width = layout.width.__getValue();
|
let width = layout.width.__getValue();
|
||||||
let hitSlop = -width + gestureResponseDistance;
|
let hitSlop = -width + gestureResponseDistance;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
minOffsetX: this._isMotionInverted() ? -5 : 5,
|
minOffsetX: isMotionInverted ? -5 : 5,
|
||||||
maxDeltaY: 20,
|
maxDeltaY: 20,
|
||||||
hitSlop: this._isMotionInverted()
|
hitSlop: isMotionInverted ? { left: hitSlop } : { right: hitSlop },
|
||||||
? { left: hitSlop }
|
|
||||||
: { right: hitSlop },
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -370,9 +371,13 @@ class StackViewLayout extends React.Component {
|
||||||
const { options } = scene.descriptor;
|
const { options } = scene.descriptor;
|
||||||
const { gestureDirection } = options;
|
const { gestureDirection } = options;
|
||||||
|
|
||||||
return typeof gestureDirection === 'string'
|
if (this._isModal()) {
|
||||||
? gestureDirection === 'inverted'
|
return gestureDirection === 'inverted';
|
||||||
: I18nManager.isRTL;
|
} else {
|
||||||
|
return typeof gestureDirection === 'string'
|
||||||
|
? gestureDirection === 'inverted'
|
||||||
|
: I18nManager.isRTL;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleHorizontalPan = nativeEvent => {
|
_handleHorizontalPan = nativeEvent => {
|
||||||
|
@ -407,7 +412,11 @@ class StackViewLayout extends React.Component {
|
||||||
|
|
||||||
// TODO: remove this __getValue!
|
// TODO: remove this __getValue!
|
||||||
let distance = layout.height.__getValue();
|
let distance = layout.height.__getValue();
|
||||||
let value = index - nativeEvent.translationY / distance;
|
|
||||||
|
let translationY = this._isMotionInverted()
|
||||||
|
? -1 * nativeEvent.translationY
|
||||||
|
: nativeEvent.translationY;
|
||||||
|
let value = index - translationY / distance;
|
||||||
return clamp(index - 1, value, index);
|
return clamp(index - 1, value, index);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -467,22 +476,38 @@ class StackViewLayout extends React.Component {
|
||||||
_handleActivateGestureVertical = () => {
|
_handleActivateGestureVertical = () => {
|
||||||
let { index } = this.props.transitionProps.navigation.state;
|
let { index } = this.props.transitionProps.navigation.state;
|
||||||
|
|
||||||
this.setState({
|
if (this._isMotionInverted()) {
|
||||||
gesturePosition: Animated.add(
|
this.setState({
|
||||||
index,
|
gesturePosition: Animated.add(
|
||||||
Animated.multiply(
|
index,
|
||||||
-1,
|
|
||||||
Animated.divide(
|
Animated.divide(
|
||||||
this.gestureY,
|
this.gestureY,
|
||||||
this.props.transitionProps.layout.height
|
this.props.transitionProps.layout.height
|
||||||
)
|
)
|
||||||
)
|
).interpolate({
|
||||||
).interpolate({
|
inputRange: [index - 1, index],
|
||||||
inputRange: [index - 1, index],
|
outputRange: [index - 1, index],
|
||||||
outputRange: [index - 1, index],
|
extrapolate: 'clamp',
|
||||||
extrapolate: 'clamp',
|
}),
|
||||||
}),
|
});
|
||||||
});
|
} else {
|
||||||
|
this.setState({
|
||||||
|
gesturePosition: Animated.add(
|
||||||
|
index,
|
||||||
|
Animated.multiply(
|
||||||
|
-1,
|
||||||
|
Animated.divide(
|
||||||
|
this.gestureY,
|
||||||
|
this.props.transitionProps.layout.height
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).interpolate({
|
||||||
|
inputRange: [index - 1, index],
|
||||||
|
outputRange: [index - 1, index],
|
||||||
|
extrapolate: 'clamp',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleReleaseHorizontal = nativeEvent => {
|
_handleReleaseHorizontal = nativeEvent => {
|
||||||
|
@ -547,12 +572,18 @@ class StackViewLayout extends React.Component {
|
||||||
|
|
||||||
// Calculate animate duration according to gesture speed and moved distance
|
// Calculate animate duration according to gesture speed and moved distance
|
||||||
const distance = layout.height.__getValue();
|
const distance = layout.height.__getValue();
|
||||||
const movedDistance = nativeEvent.translationY;
|
const isMotionInverted = this._isMotionInverted();
|
||||||
const gestureVelocity = nativeEvent.velocityY;
|
const movementDirection = isMotionInverted ? -1 : 1;
|
||||||
|
const movedDistance = movementDirection * nativeEvent.translationY;
|
||||||
|
const gestureVelocity = movementDirection * nativeEvent.velocityY;
|
||||||
const defaultVelocity = distance / ANIMATION_DURATION;
|
const defaultVelocity = distance / ANIMATION_DURATION;
|
||||||
const velocity = Math.max(Math.abs(gestureVelocity), defaultVelocity);
|
const velocity = Math.max(Math.abs(gestureVelocity), defaultVelocity);
|
||||||
const resetDuration = movedDistance / velocity;
|
const resetDuration = isMotionInverted
|
||||||
const goBackDuration = (distance - movedDistance) / velocity;
|
? (distance - movedDistance) / velocity
|
||||||
|
: movedDistance / velocity;
|
||||||
|
const goBackDuration = isMotionInverted
|
||||||
|
? movedDistance / velocity
|
||||||
|
: (distance - movedDistance) / velocity;
|
||||||
|
|
||||||
let value = this._computeVerticalGestureValue(nativeEvent);
|
let value = this._computeVerticalGestureValue(nativeEvent);
|
||||||
position.setValue(value);
|
position.setValue(value);
|
||||||
|
|
Loading…
Reference in New Issue