如何防止布局与 iOS 状态栏重叠
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42599850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to prevent layout from overlapping with iOS status bar
提问by Cliff
I am working on tutorialfor React Native navigation. I found out that all layout starts loading from top of screen instead of below of the status bar. This causes most layouts to overlap with the status bar. I can fix this by adding a padding to the view when loading them. Is this the actual way to do it? I don' think manually adding padding is an actual way to solve it. Is there a more elegant way to fix this?
我正在研究React Native 导航的教程。我发现所有布局都从屏幕顶部而不是状态栏下方开始加载。这会导致大多数布局与状态栏重叠。我可以通过在加载它们时向视图添加填充来解决这个问题。这是实际的做法吗?我不认为手动添加填充是解决它的实际方法。有没有更优雅的方法来解决这个问题?
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>
)
}
}
Below shows the screenshots before and after the padding is added.
采纳答案by Luis Rizo
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.
您可以创建一个 StatusBar 组件并在父组件中的第一个视图包装器之后首先调用它。
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>
)
}
}
回答by Greg Ennis
Now you can use SafeAreaView
which is included in React Navigation:
现在您可以使用SafeAreaView
React Navigation 中包含的内容:
<SafeAreaView>
... your content ...
</SafeAreaView>
回答by Asaf Katz
@philipheinser solution does work indeed.
@philipheinser 解决方案确实有效。
However, I would expect that React Native's StatusBarcomponent will handle that for us.
但是,我希望 React Native 的StatusBar组件会为我们处理这个问题。
It doesn't, unfortunately, but we can abstract that away quite easily by creating our own component around it:
不幸的是,它没有,但我们可以通过围绕它创建我们自己的组件来很容易地抽象出来:
./StatusBar.js
./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
./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>
)
}
前:
回答by Gaurav Saluja
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.
我们可以在 android 上获取状态栏的高度,并将 SafeAreaView 与它一起使用以使代码在两个平台上都能工作。
import { SafeAreaView, StatusBar, Platform } from 'react-native';
If we log out Platform.OS
and StatusBar.currentHeight
we get the logs,
如果我们注销Platform.OS
并StatusBar.currentHeight
获得日志,
console.log('Height on: ', Platform.OS, StatusBar.currentHeight);
Height on: android 24 and Height on: android 24
高度开启:android 24 和高度开启: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:
App.js 中的最终代码如下:
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
}
});
回答by angusyoung84
Here is a way that works for iOS:
这是一种适用于 iOS 的方法:
<View style={{height: 20, backgroundColor: 'white', marginTop: -20, zIndex: 2}}>
<StatusBar barStyle="dark-content"/></View>
回答by philipheinser
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.
您可以通过向导航栏组件添加内边距来处理此问题,或者只是在视图树顶部添加一个与状态栏具有相同高度的视图,并使用背景色,就像 facebook 应用程序那样。
回答by Safi Deraiya
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>
回答by AndyO
The react-navigation
docs have a great solution for this. First off, they recommendnotto use the SafeAreaView
included with React Native because:
该react-navigation
文档对此有一个很好的解决方案。首先,他们建议不要使用SafeAreaView
React Native 附带的,因为:
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.
虽然 React Native 导出了一个 SafeAreaView 组件,但它有一些固有的问题,即如果包含安全区域的屏幕正在动画,它会导致跳跃行为。此外,该组件仅支持 iOS 10+,不支持较旧的 iOS 版本或 Android。我们建议使用 react-native-safe-area-context 库以更可靠的方式处理安全区域。
Instead, they recommend react-native-safe-area-context- with which it would look like this:
相反,他们推荐react-native-safe-area-context- 它看起来像这样:
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={{padding: 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.)
我想指出,使用SafeAreaView
这个库提供的可能是一个更好的主意,因为现在手机的底部也可能有可以与 UI 元素重叠的元素。当然,这一切都取决于您的应用程序。(有关更多详细信息,请参阅react-navigation
我在开头链接的文档。)