iOS 13 Dark Mode in React Native with Tab Bar and Navigation Bar

Viewed 2631

I am currently trying to have a set up with a bottom tab bar, and inside the tabs, each a navigation stack with navigation bar. I use the following code based on the react navigation sample app (just minor edits on the imports, as some things were moved).

Unfortunately, only the tab bar is displayed in the dark mode color on iOS 13 simulator (dark grey), the navigation bar is white. How can I get it to display as well in the dark mode color?

import React from 'react';
import { StyleSheet, View } from 'react-native';
import {
  createAppContainer,
  Themed,
} from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import { AppearanceProvider, useColorScheme } from 'react-native-appearance';

function A() {
  return (
    <View style={styles.container}>
      <Themed.Text>B</Themed.Text>
    </View>
  );
}

A.navigationOptions = { title: 'Hello from A' };

function B() {
  return (
    <View style={styles.container}>
      <Themed.Text>B</Themed.Text>
    </View>
  );
}

B.navigationOptions = { title: 'Hello from B!!!!' };

let StackA = createStackNavigator({ A });
let StackB = createStackNavigator({ B });
let Tabs = createBottomTabNavigator({ StackA, StackB });
let Navigation = createAppContainer(Tabs);

export default function App() {
  let theme = useColorScheme();

  return (
    <AppearanceProvider>
      <Navigation theme={theme} />
    </AppearanceProvider>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});
2 Answers

https://reactnavigation.org/docs/en/themes.html#built-in-themes-inside-navigationoptions

Use theme within navigationOptions.

To integrate this with your code:

// ...
const stackDefaultNavigationOptions = ({ theme }) => { 
  // theme will be either 'light' or 'dark',
  // choose however you want to retrieve the colors for that

  // using ternary here as just a simple example,
  // but you could instead have a theme object with the keys light and dark
  return {
    title: 'Home',
    headerTintColor: theme === 'light' ? 'black' : 'white',
    headerStyle: { backgroundColor: theme === 'light' ? 'white' : 'black' },    
  }
}

const StackA = createStack({ A }, { defaultNavigationOptions: stackDefaultNavigationOptions })
const StackB = createStack({ B }, { defaultNavigationOptions: stackDefaultNavigationOptions })

// ...

export default function App() {
  let theme = useColorScheme();

  return (
    <AppearanceProvider>
        <Navigation theme={theme} />
    </AppearanceProvider>
  )
}

// ...

Use React navigation themes built-in plugin. If you use Expo, on iOS 13+ you can add the Appearance to detect preferred color scheme.

const Navigation = createAppContainer(RootStack);
export default () => <Navigation theme="light" />;

Check the docs. RN Themes

Alternatively, you can use npm package react-native-dark-mode

Related