fix: make the header appear static when sibling of headerless screen

This commit is contained in:
satyajit.happy
2019-06-14 18:56:22 +02:00
parent a8460e5a9c
commit 55c308543d
4 changed files with 54 additions and 8 deletions

View File

@@ -102,6 +102,28 @@ export function forFade({
};
}
export function forStatic({
progress: { current, next },
layouts: { screen },
}: HeaderInterpolationProps): HeaderInterpolatedStyle {
const progress = add(current, next ? next : 0);
const translateX = interpolate(progress, {
inputRange: [0, 1, 2],
outputRange: I18nManager.isRTL
? [-screen.width, 0, screen.width]
: [screen.width, 0, -screen.width],
});
const transform = [{ translateX }];
return {
leftButtonStyle: { transform },
rightButtonStyle: { transform },
titleStyle: { transform },
backgroundStyle: { transform },
};
}
export function forNoAnimation(): HeaderInterpolatedStyle {
return {};
}

View File

@@ -15,6 +15,7 @@ import {
HeaderStyleInterpolator,
} from '../../types';
import Header from './Header';
import { forStatic } from '../../TransitionConfigs/HeaderStyleInterpolators';
export type Props = {
mode: 'float' | 'screen';
@@ -65,13 +66,27 @@ export default function HeaderContainer({
}
}
// If the screen is next to a headerless screen, we need to make the header appear static
// This makes the header look like it's moving with the screen
const previousScene = self[i - 1];
const nextScene = self[i + 1];
const isHeaderStatic =
mode === 'float'
? (previousScene &&
previousScene.descriptor.options.header === null &&
// We still need to animate when coming back from next scene
// A hacky way to check this is if the next scene exists
!nextScene) ||
(nextScene && nextScene.descriptor.options.header === null)
: false;
const props = {
mode,
layout,
scene,
previous,
navigation: scene.descriptor.navigation,
styleInterpolator,
styleInterpolator: isHeaderStatic ? forStatic : styleInterpolator,
};
return (

View File

@@ -1,5 +1,12 @@
import * as React from 'react';
import { View, I18nManager, StyleSheet, ViewProps } from 'react-native';
import {
View,
I18nManager,
StyleSheet,
ViewProps,
StyleProp,
ViewStyle,
} from 'react-native';
import Animated from 'react-native-reanimated';
import {
PanGestureHandler,
@@ -37,6 +44,7 @@ type Props = ViewProps & {
close: TransitionSpec;
};
styleInterpolator: CardStyleInterpolator;
containerStyle?: StyleProp<ViewStyle>;
};
type Binary = 0 | 1;
@@ -463,6 +471,7 @@ export default class Card extends React.Component<Props> {
gesturesEnabled,
children,
styleInterpolator,
containerStyle: customContainerStyle,
...rest
} = this.props;
@@ -489,7 +498,7 @@ export default class Card extends React.Component<Props> {
/>
) : null}
<Animated.View
style={[styles.container, containerStyle]}
style={[styles.container, containerStyle, customContainerStyle]}
pointerEvents="box-none"
>
<PanGestureHandler
@@ -510,7 +519,7 @@ export default class Card extends React.Component<Props> {
active={active}
progress={this.props.current}
style={[
StyleSheet.absoluteFill,
styles.container,
transparent ? styles.transparent : styles.opaque,
]}
>

View File

@@ -128,12 +128,12 @@ export default class StackItem extends React.PureComponent<Props> {
accessibilityElementsHidden={!focused}
importantForAccessibility={focused ? 'auto' : 'no-hide-descendants'}
pointerEvents="box-none"
style={[
StyleSheet.absoluteFill,
containerStyle={
headerMode === 'float' && !hasCustomHeader
? { marginTop: floaingHeaderHeight }
: null,
]}
: null
}
style={StyleSheet.absoluteFill}
>
{headerMode === 'screen'
? renderHeader({