如何防止布局与 iOS 状态栏重叠

我正在为 教程反应本地导航工作。我发现所有的布局都是从屏幕上方而不是状态栏的下方开始加载的。这会导致大多数布局与状态栏重叠。我可以通过在加载视图时添加一个填充来解决这个问题。这是真正的方法吗?我不认为手动添加填充是一个实际的方法来解决这个问题。还有更好的解决办法吗?

import React, { Component } from 'react';
import { View, Text, Navigator } from 'react-native';


export default class MyScene extends Component {
static get defaultProps() {
return {
title : 'MyScene'
};
}
render() {
return (
<View style={{padding: 20}}> //padding to prevent overlap
<Text>Hi! My name is {this.props.title}.</Text>
</View>
)
}
}

下面显示了添加填充之前和之后的截图。 enter image description here

77659 次浏览

You can handle this by adding a padding to you navigation bar component or just ad a view that has the same hight as the statusbar at the top of your view tree with a backgroundcolor like the facebook app does this.

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>
)
}
}

 

@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:

Now you can use SafeAreaView which is included in React Navigation:

<SafeAreaView>
... your content ...
</SafeAreaView>

Here is a way that works for iOS:

<View style=\{\{height: 20, backgroundColor: 'white', marginTop: -20, zIndex: 2}}>
<StatusBar barStyle="dark-content"/></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
}
});

Just Simple User React native Default StatusBar to achieve this funcationality.

<View style={styles.container}>
<StatusBar backgroundColor={Color.TRANSPARENT} translucent={true} />
<MapView
provider={PROVIDER_GOOGLE} // remove if not using Google Maps
style={styles.map}
region=\{\{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.015,
longitudeDelta: 0.0121,
}}
/>
</View>

The react-navigation docs have a great solution for this. First off, they recommend not to use the SafeAreaView included with React Native because:

While React Native exports a SafeAreaView component, it has some inherent issues, i.e. if a screen containing safe area is animating, it causes jumpy behavior. In addition, this component only supports iOS 10+ with no support for older iOS versions or Android. We recommend to use the react-native-safe-area-context library to handle safe areas in a more reliable way.

Instead, they recommend react-native-safe-area-context - with which it would look like this:

import React, { Component } from 'react';
import { View, Text, Navigator } from 'react-native';
import { useSafeArea } from 'react-native-safe-area-context';


export default function MyScene({title = 'MyScene'}) {
const insets = useSafeArea();


return (
<View style=\{\{paddingTop: insets.top}}>
<Text>Hi! My name is {title}.</Text>
</View>
)
}

I would like to note that it's probably a better idea to use the SafeAreaView that this library offers though, since phones these days may also have elements at the bottom that can overlap UI elements. It all depends on your app of course. (For more detail on that, see the react-navigation docs I linked to in the beginning.)

If you combine SaveAreaView and StatusBar, you get it.

https://reactnative.dev/docs/statusbar https://reactnative.dev/docs/safeareaview

Just do this:

<SafeAreaView>
<View style=\{\{flex: 1}}>
<StatusBar translucent={false} backgroundColor="#fff" />


// Your dark magic here
</View>
</SafeAreaView>

[This answer is applicable to Android emulators] Hi, I have imported status bar from "react-native" and called it at the end of block with status bar style set to auto and it worked for me, the code below is for reference:

    import { SafeAreaView,Button, StyleSheet, Text, TextInput, View } from 'react-native';
import { StatusBar } from 'react-native';
export default function App() {
return (
<SafeAreaView style={styles.appContainer}>
  

  

<View >
<TextInput placeholder='Add your course goal' />
<Button title="Add Goals" />
</View>
<View>
<Text>List of goals..</Text>
</View>
<StatusBar style="auto" />
</SafeAreaView>
);
}