Мы используем MaterialTopTabNavigator (https://reactnavigation.org/docs/en/material-top-tab-navigator.html) в корне нашего приложения. Согласно документации по реактивной навигации, по умолчанию к TabNavigator должен быть применен SafeAreaView.
Кажется, что вставка применяется только к верхней части экрана, и в результате (или я могу только предположить) к нижней части не применяется отступ, что приводит к тому, что такие телефоны, как iPhoneX и другие более крупные устройства, иметь перекрытие.
Согласно документации React-Navigation, должна быть конфигурация tabBarOptions, которая позволяет вам переопределить forceInset опору SafeAreaView (safeAreaInset). Однако, убедившись, что у нас установлен последний пакет реактивной навигации, safeAreaInset нигде не найти.
Есть ли способ применить вставку непосредственно к MaterialTopTabNavigator?
Наш MainNavigator выглядит следующим образом:
const MainNavigator = createMaterialTopTabNavigator(
{
Group: {
screen: GroupStack,
navigationOptions: {
tabBarIcon: () => (
<Icon name = {'group-work'} color = {'#FFF'}/>
),
},
},
Stats: {
screen: StatisticsStack,
navigationOptions: {
tabBarIcon: () => (
<Icon name = {'insert-chart'} color = {'#FFF'}/>
),
},
},
GroupRoundsTab: {
screen: GroupRoundStack,
navigationOptions: {
tabBarIcon: () => (
<Icon name = {'group'} color = {'#FFF'}/>
),
tabBarLabel: 'Rounds',
},
},
MoreTab: {
screen: MoreStack,
navigationOptions: {
tabBarIcon: () => (
<Icon name = {'more-vert'} color = {'#FFF'}/>
),
tabBarLabel: 'More',
},
},
}, {
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false,
lazy: true,
tabBarOptions: {
upperCaseLabel: false,
labelStyle: {
fontSize: 10,
margin: 0,
},
indicatorStyle: {
backgroundColor: '#FFF',
},
style: {
backgroundColor: PRIMARY_COLOUR,
},
tabStyle: {
height: 50,
alignItems: 'center',
justifyContent: 'center',
},
showIcon: true,
},
});
Единственное решение, которое мы нашли, — это обернуть все наше приложение в SafeAreaView следующим образом:
<StatusBar barStyle = "dark-content"/>
<SafeAreaView style = {{ flex: 1 }}>
<AppContainer/>
<OfflineNotice/>
</SafeAreaView>
Огромным недостатком здесь является то, что любые StackNavigator в основной TabNavigation получают двойное дополнение, потому что реагирующая навигация снова автоматически применяет SafeAreaView на этих экранах.





Вы можете добавить оболочку SafeAreaView вокруг верхней вкладки следующим образом:
import {
MaterialTopTabBar,
SafeAreaView,
createAppContainer,
createMaterialTopTabNavigator,
} from 'react-navigation';
class MaterialTopTabBarWrapper extends React.Component {
render() {
return (
<SafeAreaView
style = {{ backgroundColor: '#2196f3' }}
forceInset = {{ top: 'always', horizontal: 'never', bottom: 'never' }}>
<MaterialTopTabBar {...this.props} />
</SafeAreaView>
);
}
}
let Tabs = createMaterialTopTabNavigator(
{
/* your routes */
},
{
tabBarComponent: MaterialTopTabBarWrapper,
}
);
Я решил не слишком сильно взламывать оригинальный навигатор. Вместо того, чтобы добавлять дополнительную сложность, я просто добавил следующие свойства навигации по умолчанию для каждого из маршрутов StackNavigator, чтобы гарантировать, что они не добавляют дополнительных отступов в результате рендеринга в исходном SafeAreaView.
defaultNavigationOptions: {
headerForceInset: {
top: 'never',
bottom: 'never',
},
},
Это гарантирует, что все внутренние экраны и внешние экраны заполнены правильно. Не идеальное решение, но, по крайней мере, его легко настроить, если в дальнейшем необходимо внести изменения.