React Native에서 iOS SafeArea 대응하기

문제 상황

iPhone X 이상 기기에서 상단 노치와 하단 홈 인디케이터 영역에 컨텐츠가 겹쳐 보이는 이슈가 발생했다. 기존에 StatusBar height를 직접 계산해서 padding을 주던 방식이 더 이상 통하지 않았다.

SafeAreaView 적용

React Native 0.50.1부터 추가된 SafeAreaView를 적용했다.

import { SafeAreaView, StyleSheet, View, Text } from 'react-native';

const App = () => {
  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.content}>
        <Text>컨텐츠</Text>
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  content: {
    flex: 1,
  },
});

주의사항

SafeAreaView는 iOS 11 이상에서만 동작한다. 그 이하 버전에서는 일반 View처럼 동작하므로 별도 분기 처리는 불필요했다.

다만 SafeAreaView를 중첩해서 사용할 경우 padding이 중복 적용되는 문제가 있었다. 최상위 컴포넌트 하나에만 적용하고, 하위에서는 일반 View를 사용하는 것으로 해결했다.

배경색이 있는 경우 SafeAreaView의 backgroundColor를 명시적으로 지정해야 노치 영역까지 배경색이 적용된다.

react-native-safe-area-context

더 세밀한 제어가 필요한 경우 react-native-safe-area-context 라이브러리 사용을 고려할 예정이다. useSafeArea hook으로 각 edge별 inset 값을 직접 가져올 수 있다고 한다.