From bb09b7d13d1c2be50500bff3a0da4b174ea86d1d Mon Sep 17 00:00:00 2001 From: Peter Steffey Date: Tue, 6 Feb 2018 13:39:41 -0500 Subject: [PATCH] Issue #2794 - Tab bar fix - Continued from #3041 (#3267) * Fixing iPad iOS 11 Tab Bar Bottom Behavior with changing widths via Multitasking * Adding width constrained check * Moving to only Platform.isPad (no more layout-based tests) * Remove type import --- .../__snapshots__/TabNavigator-test.js.snap | 99 ++++++++------ .../src/views/TabView/TabBarBottom.js | 126 +++++++++++++----- .../__snapshots__/TabView-test.js.snap | 99 ++++++++------ 3 files changed, 207 insertions(+), 117 deletions(-) diff --git a/packages/react-navigation/src/navigators/__tests__/__snapshots__/TabNavigator-test.js.snap b/packages/react-navigation/src/navigators/__tests__/__snapshots__/TabNavigator-test.js.snap index 453a12fb..33e23bd7 100644 --- a/packages/react-navigation/src/navigators/__tests__/__snapshots__/TabNavigator-test.js.snap +++ b/packages/react-navigation/src/navigators/__tests__/__snapshots__/TabNavigator-test.js.snap @@ -105,68 +105,81 @@ exports[`TabNavigator renders successfully 1`] = ` "alignItems": "center", "backgroundColor": "rgba(0, 0, 0, 0)", "flex": 1, - "justifyContent": "flex-end", } } testID={undefined} > - + + + + + > + Welcome anonymous + - - Welcome anonymous - diff --git a/packages/react-navigation/src/views/TabView/TabBarBottom.js b/packages/react-navigation/src/views/TabView/TabBarBottom.js index 133069fa..e4f71f1b 100644 --- a/packages/react-navigation/src/views/TabView/TabBarBottom.js +++ b/packages/react-navigation/src/views/TabView/TabBarBottom.js @@ -13,7 +13,8 @@ import withOrientation from '../withOrientation'; const majorVersion = parseInt(Platform.Version, 10); const isIos = Platform.OS === 'ios'; -const useHorizontalTabs = majorVersion >= 11 && isIos; +const isIOS11 = majorVersion >= 11 && isIos; +const defaultMaxTabBarItemWidth = 125; class TabBarBottom extends React.PureComponent { // See https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/UIKitUICatalog/UITabBar.html @@ -25,6 +26,7 @@ class TabBarBottom extends React.PureComponent { showLabel: true, showIcon: true, allowFontScaling: true, + adaptive: isIOS11, }; _renderLabel = scene => { @@ -56,19 +58,18 @@ class TabBarBottom extends React.PureComponent { const tintColor = scene.focused ? activeTintColor : inactiveTintColor; const label = this.props.getLabel({ ...scene, tintColor }); - let marginLeft = 0; - if (isLandscape && showIcon && useHorizontalTabs) { - marginLeft = LABEL_LEFT_MARGIN; - } - let marginTop = 0; - if (!isLandscape && showIcon && useHorizontalTabs) { - marginTop = LABEL_TOP_MARGIN; - } if (typeof label === 'string') { return ( {label} @@ -104,7 +105,7 @@ class TabBarBottom extends React.PureComponent { inactiveTintColor={inactiveTintColor} renderIcon={renderIcon} scene={scene} - style={showLabel && useHorizontalTabs ? {} : styles.icon} + style={showLabel && this._shouldUseHorizontalTabs() ? {} : styles.icon} /> ); }; @@ -115,6 +116,64 @@ class TabBarBottom extends React.PureComponent { return testIDProps; }; + _tabItemMaxWidth() { + const { tabStyle, layout } = this.props; + let maxTabBarItemWidth; + + const flattenedTabStyle = StyleSheet.flatten(tabStyle); + + if (flattenedTabStyle) { + if (typeof flattenedTabStyle.width === 'number') { + maxTabBarItemWidth = flattenedTabStyle.width; + } else if ( + typeof flattenedTabStyle.width === 'string' && + flattenedTabStyle.endsWith('%') + ) { + const width = parseFloat(flattenedTabStyle.width); + if (Number.isFinite(width)) { + maxTabBarItemWidth = layout.width * (width / 100); + } + } else if (typeof flattenedTabStyle.maxWidth === 'number') { + maxTabBarItemWidth = flattenedTabStyle.maxWidth; + } else if ( + typeof flattenedTabStyle.maxWidth === 'string' && + flattenedTabStyle.endsWith('%') + ) { + const width = parseFloat(flattenedTabStyle.maxWidth); + if (Number.isFinite(width)) { + maxTabBarItemWidth = layout.width * (width / 100); + } + } + } + + if (!maxTabBarItemWidth) { + maxTabBarItemWidth = defaultMaxTabBarItemWidth; + } + + return maxTabBarItemWidth; + } + + _shouldUseHorizontalTabs() { + const { routes } = this.props.navigation.state; + const { isLandscape, layout, adaptive, tabStyle } = this.props; + + if (!adaptive) { + return false; + } + + let tabBarWidth = layout.width; + if (tabBarWidth === 0) { + return Platform.isPad; + } + + if (!Platform.isPad) { + return isLandscape; + } else { + const maxTabBarItemWidth = this._tabItemMaxWidth(); + return routes.length * maxTabBarItemWidth <= tabBarWidth; + } + } + render() { const { position, @@ -136,9 +195,9 @@ class TabBarBottom extends React.PureComponent { const tabBarStyle = [ styles.tabBar, - isLandscape && useHorizontalTabs - ? styles.tabBarLandscape - : styles.tabBarPortrait, + this._shouldUseHorizontalTabs() && !Platform.isPad + ? styles.tabBarCompact + : styles.tabBarRegular, style, ]; @@ -178,17 +237,19 @@ class TabBarBottom extends React.PureComponent { : jumpToIndex(index) } > - - {this._renderIcon(scene)} - {this._renderLabel(scene)} + + + {this._renderIcon(scene)} + {this._renderLabel(scene)} + ); @@ -199,8 +260,6 @@ class TabBarBottom extends React.PureComponent { } } -const LABEL_LEFT_MARGIN = 20; -const LABEL_TOP_MARGIN = 15; const styles = StyleSheet.create({ tabBar: { backgroundColor: '#F7F7F7', // Default background color in iOS 10 @@ -208,16 +267,15 @@ const styles = StyleSheet.create({ borderTopColor: 'rgba(0, 0, 0, .3)', flexDirection: 'row', }, - tabBarLandscape: { + tabBarCompact: { height: 29, }, - tabBarPortrait: { + tabBarRegular: { height: 49, }, tab: { flex: 1, alignItems: isIos ? 'center' : 'stretch', - justifyContent: 'flex-end', }, tabPortrait: { justifyContent: 'flex-end', @@ -232,9 +290,15 @@ const styles = StyleSheet.create({ }, label: { textAlign: 'center', + backgroundColor: 'transparent', + }, + labelBeneath: { fontSize: 10, marginBottom: 1.5, - backgroundColor: 'transparent', + }, + labelBeside: { + fontSize: 13, + marginLeft: 20, }, }); diff --git a/packages/react-navigation/src/views/__tests__/__snapshots__/TabView-test.js.snap b/packages/react-navigation/src/views/__tests__/__snapshots__/TabView-test.js.snap index 3f75ccaa..904069ec 100644 --- a/packages/react-navigation/src/views/__tests__/__snapshots__/TabView-test.js.snap +++ b/packages/react-navigation/src/views/__tests__/__snapshots__/TabView-test.js.snap @@ -61,68 +61,81 @@ exports[`TabBarBottom renders successfully 1`] = ` "alignItems": "center", "backgroundColor": "rgba(0, 0, 0, 0)", "flex": 1, - "justifyContent": "flex-end", } } testID={undefined} > - + + + + + > + s1 + - - s1 -