From 7fa0ef3aeeee8fd54be1e55cf48764c517aa45fb Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Fri, 12 Jan 2018 15:34:40 -0800 Subject: [PATCH] Handle translucent status bar within Expo automatically. - Escape hatch of `ReactNavigation.SafeAreaView.setStatusBarHeight()`. - `if (Platform.OS === 'android') { ReactNavigation.SafeAreaView.setStatusBarHeight(0) }` to revert to old behavior. --- src/views/SafeAreaView.js | 27 +++++++++++++++++++++++---- src/views/TabView/TabBarTop.js | 17 ++++++++++++----- src/views/TabView/TabView.js | 2 ++ 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/views/SafeAreaView.js b/src/views/SafeAreaView.js index 7d044a3..e8514b1 100644 --- a/src/views/SafeAreaView.js +++ b/src/views/SafeAreaView.js @@ -52,7 +52,26 @@ const isIPad = (() => { return true; })(); +let _customStatusBarHeight = null; const statusBarHeight = isLandscape => { + if (_customStatusBarHeight !== null) { + return _customStatusBarHeight; + } + + /** + * This is a temporary workaround because we don't have a way to detect + * if the status bar is translucent or opaque. If opaque, we don't need to + * factor in the height here; if translucent (content renders under it) then + * we do. + */ + if (Platform.OS === 'android') { + if (global.Expo) { + return global.Expo.Constants.statusBarHeight; + } else { + return 0; + } + } + if (isIPhoneX) { return isLandscape ? 0 : 44; } @@ -77,6 +96,10 @@ const doubleFromPercentString = percent => { }; class SafeView extends Component { + static setStatusBarHeight = height => { + _customStatusBarHeight = height; + }; + state = { touchesTop: true, touchesBottom: true, @@ -100,10 +123,6 @@ class SafeView extends Component { render() { const { forceInset = false, isLandscape, children, style } = this.props; - if (Platform.OS !== 'ios') { - return {this.props.children}; - } - const safeAreaStyle = this._getSafeAreaStyle(); return ( diff --git a/src/views/TabView/TabBarTop.js b/src/views/TabView/TabBarTop.js index b5949df..7d5e8b6 100644 --- a/src/views/TabView/TabBarTop.js +++ b/src/views/TabView/TabBarTop.js @@ -4,6 +4,7 @@ import * as React from 'react'; import { Animated, StyleSheet } from 'react-native'; import { TabBar } from 'react-native-tab-view'; import TabBarIcon from './TabBarIcon'; +import SafeAreaView from '../SafeAreaView'; import type { NavigationAction, @@ -24,6 +25,7 @@ type Props = { upperCaseLabel: boolean, allowFontScaling: boolean, position: Animated.Value, + tabBarPosition: string, navigation: NavigationScreenProp, jumpToIndex: (index: number) => void, getLabel: (scene: TabScene) => ?(React.Node | string), @@ -53,6 +55,7 @@ export default class TabBarTop extends React.PureComponent { _renderLabel = (scene: TabScene) => { const { position, + tabBarPosition, navigation, activeTintColor, inactiveTintColor, @@ -81,12 +84,16 @@ export default class TabBarTop extends React.PureComponent { const label = this.props.getLabel({ ...scene, tintColor }); if (typeof label === 'string') { return ( - - {upperCaseLabel ? label.toUpperCase() : label} - + + {upperCaseLabel ? label.toUpperCase() : label} + + ); } if (typeof label === 'function') { diff --git a/src/views/TabView/TabView.js b/src/views/TabView/TabView.js index 62eb73f..0d28612 100644 --- a/src/views/TabView/TabView.js +++ b/src/views/TabView/TabView.js @@ -145,10 +145,12 @@ class TabView extends React.PureComponent { if (typeof TabBarComponent === 'undefined') { return null; } + return (