레이아웃이 iOS 상태 표시 줄과 겹치는 것을 방지하는 방법


81

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

아래는 패딩이 추가되기 전과 후의 스크린 샷입니다. 여기에 이미지 설명 입력


13
좋은 질문이지만 아마도 이미지를 다듬을 수 있습니다.
Quv

stackoverflow.com/a/39300715/1540350 <-이 답변은 여기에 언급 된 문제를 해결할뿐만 아니라 iOS 및 Android에서 상태 표시 줄의 배경에 색상을 지정할 수도 있습니다.
Martin Braun

답변:


36

이것을 고치는 아주 간단한 방법이 있습니다. 구성 요소를 만듭니다.

StatusBar 구성 요소를 만들고 부모 구성 요소의 첫 번째보기 래퍼 후에 먼저 호출 할 수 있습니다.

내가 사용하는 코드는 다음과 같습니다.

'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

이를 수행하고 기본 구성 요소로 내 보낸 후 다음과 같이 호출하십시오.

import StatusBarBackground from './YourPath/StatusBarBackground'

export default class MyScene extends Component {
  render(){
    return(
      <View>
        <StatusBarBackground style={{backgroundColor:'midnightblue'}}/>
      </View>
    )
  }
}

 


MidnightBlue: 기본 반작용에 의해 말, 잘못되었습니다 잘못된 소품 : 경고 : 실패 소품 유형이 backgroundColor공급
랩터

2
이어야합니다 midnightblue.
bblincoe

19
iOS 상태 표시 줄은 수정 크기가 아닙니다. Wi-Fi를 공유하거나 통화 중일 때 더 클 수 있습니다.
edA-qa mort-ora-y

1
redux와 함께 React 탐색 연결을 사용할 때 어떻게 사용합니까? 모든 페이지는 스택 탐색기 또는 탭 탐색기 (중첩)에 있고 redux와 연결됩니다.
Yasir

5
반응 네이티브 컴포넌트 "StatusBar"를 가져온 다음 사용하는 경우 : height: (Platform.OS === 'ios') ? 20 : StatusBar.currentHeight,대신 ? 20 : 0,Android에서 동일한 결과를 얻습니다.
mrroot5

60

이제 SafeAreaViewReact Navigation에 포함 된 것을 사용할 수 있습니다 .

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

3
이 구성 요소는 react-navigation이제 기본적으로 포함되어 있습니다.
Aᴄʜᴇʀᴏɴғᴀɪʟ

15
이것은 상태 표시 줄 겹침 문제를 해결하지 못합니다. 내 앱을 SafeAreaView로 래핑했는데 내 앱이 여전히 상태 표시 줄과 겹칩니다. 아이폰 X 노치 / 둥근 모서리의 상황에 맞도록 할 것
izikandrw

앱을 래핑하지 않고 화면을 래핑합니다.
Greg Ennis

오, 멋지네요! 나는 그것을 좋아한다.
Asaf Katz

1
@AndreFigueiredo 맞지 않습니다. 한이> 아이폰 OS (11)의로, 모든 아이폰 장치에서 잘 작동
동료 낯선 사람이

20

나는 이것을 위해 더 간단한 방법을 시도했습니다.

Android에서 상태 표시 줄의 높이를 가져 와서 SafeAreaView를 함께 사용하여 코드가 두 플랫폼 모두에서 작동하도록 할 수 있습니다.

import { SafeAreaView, StatusBar, Platform } from 'react-native';

로그 아웃 Platform.OS하고 로그 StatusBar.currentHeight를 얻으면

console.log('Height on: ', Platform.OS, StatusBar.currentHeight);

높이 : android 24 및 높이 : android 24

이제 선택적으로 컨테이너 뷰에 여백 / 패딩을 추가 할 수 있습니다.

paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0

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

1
나는 그것을 안드로이드에서 시도했고 작동하고 있습니다. 아직 iOS에서 테스트 할 수는 없지만 iOS에서 SafeArea가 무엇인지 알기 때문에 거기에서도 작동 할 것이라고 확신합니다.
manuelwaldner

1
*** 이것은 허용 된 답변으로 설정되어야합니다 *** 여기에있는 다른 솔루션은 자체 단일 테스트 상황을 기반으로 임의의 고정 높이를 제공합니다
mcmonkeys1

완벽한 대답이지만 SafeAreaView는 11 이하 버전의 iPhone 장치에는 적용되지 않습니다
Pradeep

잘 작동했습니다. 감사!
bruxo00 20.04.05

16

@philipheinser 솔루션은 실제로 작동합니다.

그러나 React Native의 StatusBar 구성 요소가이를 처리 할 것으로 예상합니다 .

안타깝게도 그렇지는 않지만 주변에 자체 구성 요소를 만들어 쉽게 추상화 할 수 있습니다.

./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>
    )
}
전에:

후:


4

react-navigation문서는이에 대한 좋은 해결책을 가지고 있습니다. 먼저 다음 과 같은 이유로 React Native에 포함 된 것을 사용 하지 않는 것이 좋습니다 .SafeAreaView

React Native가 SafeAreaView 구성 요소를 내보내는 동안 몇 가지 고유 한 문제가 있습니다. 즉, 안전 영역이 포함 된 화면이 애니메이션되는 경우 비정상적인 동작이 발생합니다. 또한이 구성 요소는 이전 iOS 버전 또는 Android를 지원하지 않고 iOS 10 이상 만 지원합니다. 보다 안정적인 방식으로 안전한 영역을 처리하려면 react-native-safe-area-context 라이브러리를 사용하는 것이 좋습니다.

대신 다음과 같은 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={{paddingTop: insets.top}}>
            <Text>Hi! My name is {title}.</Text>
        </View> 
    )   
}

SafeAreaView요즘에는 휴대폰 하단에 UI 요소와 겹칠 수있는 요소가있을 수 있기 때문에이 라이브러리가 제공 하는 것을 사용하는 것이 아마도 더 나은 아이디어라는 점에 주목하고 싶습니다 . 물론 앱에 따라 다릅니다. (자세한 내용 react-navigation은 처음에 링크 한 문서를 참조하십시오 .)


2

iOS에서 작동하는 방법은 다음과 같습니다 .

<View style={{height: 20, backgroundColor: 'white', marginTop: -20, zIndex: 2}}>
   <StatusBar barStyle="dark-content"/></View>

1

탐색 모음 구성 요소에 패딩을 추가하거나 페이스 북 앱처럼 배경색을 사용하여 뷰 트리 상단의 상태 표시 줄과 높이가 같은 뷰를 광고하여이를 처리 할 수 ​​있습니다.


6
그 높이 값은 고정되어 있으며 어떤 전화기를 가지고 있어도 변경되지 않습니까? 그렇다면 iOS / Android의 정확한 특정 값에 대한 정보는 어디에서 찾을 수 있습니까?
nbkhope

0

이 기능을 달성하기 위해 단순한 사용자 반응 네이티브 기본 상태 표시 줄.

<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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.