diff --git a/src/navigators/__tests__/__snapshots__/NestedNavigator-test.js.snap b/src/navigators/__tests__/__snapshots__/NestedNavigator-test.js.snap index eeb13be..c9a22d7 100644 --- a/src/navigators/__tests__/__snapshots__/NestedNavigator-test.js.snap +++ b/src/navigators/__tests__/__snapshots__/NestedNavigator-test.js.snap @@ -156,6 +156,7 @@ exports[`Nested navigators renders succesfully as direct child 1`] = ` collapsable={undefined} style={ Object { + "backgroundColor": "#F7F7F7", "transform": Array [ Object { "translateX": 0, @@ -265,6 +266,7 @@ exports[`Nested navigators renders succesfully as direct child 1`] = ` collapsable={undefined} style={ Object { + "backgroundColor": "#F7F7F7", "transform": Array [ Object { "translateX": 0, diff --git a/src/navigators/__tests__/__snapshots__/StackNavigator-test.js.snap b/src/navigators/__tests__/__snapshots__/StackNavigator-test.js.snap index 247a400..9535462 100644 --- a/src/navigators/__tests__/__snapshots__/StackNavigator-test.js.snap +++ b/src/navigators/__tests__/__snapshots__/StackNavigator-test.js.snap @@ -83,6 +83,7 @@ exports[`StackNavigator applies correct values when headerRight is present 1`] = collapsable={undefined} style={ Object { + "backgroundColor": "#F7F7F7", "transform": Array [ Object { "translateX": 0, @@ -288,6 +289,7 @@ exports[`StackNavigator renders successfully 1`] = ` collapsable={undefined} style={ Object { + "backgroundColor": "#F7F7F7", "transform": Array [ Object { "translateX": 0, diff --git a/src/views/Header/Header.js b/src/views/Header/Header.js index 2319ec6..8cbb2f7 100644 --- a/src/views/Header/Header.js +++ b/src/views/Header/Header.js @@ -491,7 +491,12 @@ class Header extends React.PureComponent { const forceInset = headerForceInset || { top: 'always', bottom: 'never' }; return ( - + {options.headerBackground} @@ -529,9 +534,11 @@ if (Platform.OS === 'ios') { }; } +const DEFAULT_BACKGROUND_COLOR = Platform.OS === 'ios' ? '#F7F7F7' : '#FFF'; + const styles = StyleSheet.create({ container: { - backgroundColor: Platform.OS === 'ios' ? '#F7F7F7' : '#FFF', + backgroundColor: DEFAULT_BACKGROUND_COLOR, ...platformContainerStyles, }, transparentContainer: { diff --git a/src/views/Header/HeaderStyleInterpolator.js b/src/views/Header/HeaderStyleInterpolator.js index f3b6271..76d1bce 100644 --- a/src/views/Header/HeaderStyleInterpolator.js +++ b/src/views/Header/HeaderStyleInterpolator.js @@ -58,7 +58,15 @@ function forLayout(props) { const { first, last } = interpolate; const index = scene.index; - const width = layout.initWidth; + + // We really shouldn't render the scene at all until we know the width of the + // stack. That said, in every case that I have ever seen, this has just been + // the full width of the window. This won't continue to be true if we support + // layouts like iPad master-detail. For now, in order to solve + // https://github.com/react-navigation/react-navigation/issues/4264, I have + // opted for the heuristic that we will use the window width until we have + // measured (and they will usually be the same). + const width = layout.initWidth || Dimensions.get('window').width; // Make sure the header stays hidden when transitioning between 2 screens // with no header. diff --git a/src/views/StackView/StackViewLayout.js b/src/views/StackView/StackViewLayout.js index d018faa..1d4f931 100644 --- a/src/views/StackView/StackViewLayout.js +++ b/src/views/StackView/StackViewLayout.js @@ -68,6 +68,20 @@ const animatedSubscribeValue = animatedValue => { } }; +const getDefaultHeaderHeight = isLandscape => { + if (Platform.OS === 'ios') { + if (isLandscape && !Platform.isPad) { + return 32; + } else if (IS_IPHONE_X) { + return 88; + } else { + return 64; + } + } else { + return 56; + } +}; + class StackViewLayout extends React.Component { /** * Used to identify the starting point of the position when the gesture starts, such that it can @@ -89,10 +103,18 @@ class StackViewLayout extends React.Component { */ _immediateIndex = null; - state = { - // Used when card's header is null and mode is float to make switch animation work correctly - floatingHeaderHeight: 0, - }; + constructor(props) { + super(props); + + this.state = { + // Used when card's header is null and mode is float to make transition + // between screens with headers and those without headers smooth. + // This is not a great heuristic here. We don't know synchronously + // on mount what the header height is so we have just used the most + // common cases here. + floatingHeaderHeight: getDefaultHeaderHeight(props.isLandscape), + }; + } _renderHeader(scene, headerMode) { const { options } = scene.descriptor;