How to prevent layout from overlapping with iOS status bar
There is a very simple way to fix this. Make a component.
You can create a StatusBar component and call it first after the first view wrapper in your parent components.
Here is the code for the one I use:
'use strict'
import React, {Component} from 'react';
import {View, Text, StyleSheet, Platform} from 'react-native';
class StatusBarBackground extends Component{
render(){
return(
<View style={[styles.statusBarBackground, this.props.style || {}]}> //This part is just so you can change the color of the status bar from the parents by passing it as a prop
</View>
);
}
}
const styles = StyleSheet.create({
statusBarBackground: {
height: (Platform.OS === 'ios') ? 18 : 0, //this is just to test if the platform is iOS to give it a height of 18, else, no height (Android apps have their own status bar)
backgroundColor: "white",
}
})
module.exports= StatusBarBackground
After doing this and exporting it to your main component, call it like this:
import StatusBarBackground from './YourPath/StatusBarBackground'
export default class MyScene extends Component {
render(){
return(
<View>
<StatusBarBackground style={{backgroundColor:'midnightblue'}}/>
</View>
)
}
}
I tried a more simple way for this.
We can get the height of Status Bar on android and use SafeAreaView along with it to make the code work on both platforms.
import { SafeAreaView, StatusBar, Platform } from 'react-native';
If we log out Platform.OS
and StatusBar.currentHeight
we get the logs,
console.log('Height on: ', Platform.OS, StatusBar.currentHeight);
Height on: android 24 and Height on: android 24
We can now optionally add margin/padding to our container view using
paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0
The final code in App.js is below:
export default class App extends React.Component {
render() {
return (
<SafeAreaView style={{ flex: 1, backgroundColor: "#fff" }}>
<View style={styles.container}>
<Text>Hello World</Text>
</View>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0
}
});
Now you can use SafeAreaView
which is included in React Navigation:
<SafeAreaView>
... your content ...
</SafeAreaView>
@philipheinser solution does work indeed.
However, I would expect that React Native's StatusBar component will handle that for us.
It doesn't, unfortunately, but we can abstract that away quite easily by creating our own component around it:
./StatusBar.js
import React from 'react';
import { View, StatusBar, Platform } from 'react-native';
// here, we add the spacing for iOS
// and pass the rest of the props to React Native's StatusBar
export default function (props) {
const height = (Platform.OS === 'ios') ? 20 : 0;
const { backgroundColor } = props;
return (
<View style={{ height, backgroundColor }}>
<StatusBar { ...props } />
</View>
);
}
./index.js
import React from 'react';
import { View } from 'react-native';
import StatusBar from './StatusBar';
export default function App () {
return (
<View>
<StatusBar backgroundColor="#2EBD6B" barStyle="light-content" />
{ /* rest of our app */ }
</View>
)
}
Before:
After: