Render NavigationHeader correctly with hidden status bar

Summary:
Currently, the NavigationExperimental `Header` only renders correctly on iOS when the system status bar is visible. There are legitimate reasons to hide the status bar, especially when displaying in landscape.

This PR adds a `statusBarHeight` prop to the header, which defaults to 20 on iOS and 0 (no status bar) on Android. Changing this value causes the extra space at the top of the header reserved for the status bar to change.

I've tested this change in my own app on iOS with `statusBarHeight` set to 0, 20, and `undefined`, and ensured that it works correctly.
Closes https://github.com/facebook/react-native/pull/8983

Differential Revision: D3668637

fbshipit-source-id: 777a0c53e8fd1caa35ce4980ca3118adcf83b62d
This commit is contained in:
Kyle Corbitt 2016-08-04 11:31:07 -07:00 committed by Facebook Github Bot 8
parent 5d0131d31b
commit 341b29da71
1 changed files with 18 additions and 6 deletions

View File

@ -62,6 +62,7 @@ type DefaultProps = {
renderLeftComponent: SubViewRenderer,
renderRightComponent: SubViewRenderer,
renderTitleComponent: SubViewRenderer,
statusBarHeight: number | Animated.Value,
};
type Props = NavigationSceneRendererProps & {
@ -71,6 +72,7 @@ type Props = NavigationSceneRendererProps & {
renderTitleComponent: SubViewRenderer,
style?: any,
viewProps?: any,
statusBarHeight: number | Animated.Value,
};
type SubViewName = 'left' | 'title' | 'right';
@ -103,6 +105,8 @@ class NavigationHeader extends React.Component<DefaultProps, Props, any> {
renderRightComponent: (props: SubViewProps) => {
return null;
},
statusBarHeight: STATUSBAR_HEIGHT,
};
static propTypes = {
@ -112,6 +116,7 @@ class NavigationHeader extends React.Component<DefaultProps, Props, any> {
renderRightComponent: PropTypes.func,
renderTitleComponent: PropTypes.func,
style: View.propTypes.style,
statusBarHeight: PropTypes.number,
viewProps: PropTypes.shape(View.propTypes),
};
@ -132,12 +137,22 @@ class NavigationHeader extends React.Component<DefaultProps, Props, any> {
return props;
});
const barHeight = (this.props.statusBarHeight instanceof Animated.Value)
? Animated.add(this.props.statusBarHeight, new Animated.Value(APPBAR_HEIGHT))
: APPBAR_HEIGHT + this.props.statusBarHeight;
return (
<View style={[ styles.appbar, style ]} {...viewProps}>
<Animated.View style={[
styles.appbar,
{ height: barHeight },
style
]}
{...viewProps}
>
{scenesProps.map(this._renderLeft, this)}
{scenesProps.map(this._renderTitle, this)}
{scenesProps.map(this._renderRight, this)}
</View>
</Animated.View>
);
}
@ -206,6 +221,7 @@ class NavigationHeader extends React.Component<DefaultProps, Props, any> {
key={name + '_' + key}
style={[
styles[name],
{ marginTop: this.props.statusBarHeight },
styleInterpolator(props),
]}>
{subView}
@ -227,7 +243,6 @@ const styles = StyleSheet.create({
borderBottomWidth: Platform.OS === 'ios' ? StyleSheet.hairlineWidth : 0,
elevation: 4,
flexDirection: 'row',
height: APPBAR_HEIGHT + STATUSBAR_HEIGHT,
justifyContent: 'flex-start',
left: 0,
marginBottom: 16, // This is needed for elevation shadow
@ -239,7 +254,6 @@ const styles = StyleSheet.create({
title: {
bottom: 0,
left: APPBAR_HEIGHT,
marginTop: STATUSBAR_HEIGHT,
position: 'absolute',
right: APPBAR_HEIGHT,
top: 0,
@ -248,14 +262,12 @@ const styles = StyleSheet.create({
left: {
bottom: 0,
left: 0,
marginTop: STATUSBAR_HEIGHT,
position: 'absolute',
top: 0,
},
right: {
bottom: 0,
marginTop: STATUSBAR_HEIGHT,
position: 'absolute',
right: 0,
top: 0,