React Native 앱에 Notch 지원 추가: Android, iOS 및 웹

이 튜토리얼에서는 몇 줄의 코드만으로 Android, iOS 및 웹에서 노치("디스플레이 컷아웃"이라고도 함)를 올바르게 지원하는 방법을 배웁니다.

다음은 Double cutout를 보여주는 Android 에뮬레이터입니다.



If you don't have an Android device with Notch, open an Android Emulator and emulate the display cutout by going to Android Settings > System > Advanced > Developer options > Display cutout > Double cutout



위의 스크린샷에서 배경 화면이 노치 뒤에 표시되는 것을 볼 수 있습니다. 이것이 올바른 동작이며 앱도 그렇게 해야 합니다.

그러나 간단한 앱을 렌더링할 때 어떤 일이 발생하는지 살펴보겠습니다.



기본적으로 앱은 노치를 처리하지 않습니다. 위의 이미지에서 두 개의 검은색 막대를 렌더링하여 사용자에게 화면이 더 작게 느껴지도록 하는 것을 볼 수 있습니다. 좋지 않습니다. 수정하겠습니다.

여기서 재미가 시작됩니다. 몇 시간 동안 다른 방법을 연구하고 시도한 후 이것이 MainActivity.java에 추가해야 하는 것임을 알았습니다.

public class MainActivity extends ReactActivity {

+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+            WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
+            layoutParams.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+            getWindow().setAttributes(layoutParams);
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
+        }
+
+        super.onCreate(savedInstanceState);
+    }

이 코드는 세 가지 작업을 수행합니다. 검은 막대 표시를 중지하려면 layoutInDisplayCutoutModeedgeInsets로 설정하고, 노치 및 탐색 버튼 뒤에 앱을 렌더링하려면 statusnavigationtranslucent로 설정합니다.

이 코드를 추가한 후의 결과는 다음과 같습니다.



예! 그것은 개선입니다. 이제 우리는 전체 화면을 사용합니다. 그러나 텍스트 내용이 노치에 의해 가려지는 것을 볼 수 있습니다.

React Native에는 SafeAreaView 이라는 내장 구성 요소가 있습니다. 이 정확한 문제를 해결하지만... iPhone X에서만 가능합니다. 여전히 Android를 지원하지 않습니다.

덕분에 react-native-safe-area-context 를 사용할 수 있습니다. iOS, Android, 웹 등 원하는 모든 플랫폼을 지원합니다!

If you use Expo, this lib will be included on SDK v35

If you use react-native < 0.60, you can apply this patch using patch-package



API는 다음과 같습니다.

const safeAreaInsets = useSafeArea()

그리고 패딩을 View에 추가합니다.

<View
  style={{
    flex: 1,
    paddingTop: safeAreaInsets.top,
    paddingBottom: safeAreaInsets.bottom,
    paddingLeft: safeAreaInsets.left,
    paddingRight: safeAreaInsets.right,
  }}
>

최종 결과는 다음과 같습니다.



완벽하게 작동합니다 🎉🎉🎉
Android가 준비되었습니다. 이제 iOS 앱이 어떻게 보이는지 살펴보겠습니다.



iOS도 이미 완벽합니다! 🎉
3개 중 2개입니다. 웹은 어떻습니까? 보자:



흠, 웹에 여전히 검은색 막대가 표시됩니다.

If your app doesn’t support web yet, check out my other tutorial:



하지만 이는 수정하기 쉽습니다. viewport-fit=cover 메타 태그에 viewport를 추가하기만 하면 됩니다.

-<meta name="viewport" content="width=device-width, initial-scale=1">
+<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">



그리고 짜잔! 저희 앱은 이제 iOS, Android 및 웹에서 노치를 제대로 지원합니다! 그리고 다시 한 번 멋진react-native-safe-area-context 덕분에 쉬웠습니다.

위의 코드가 포함된 gist이 있습니다.

읽어 주셔서 감사합니다!

좋은 웹페이지 즐겨찾기