2019.04.01

iPhoneXS Max, XR でreact-navigation のヘッダが崩れる問題の解決方法

こんにちは。次世代システム研究室のT.M. です。

はじめに

3/27 からiOS アプリの審査において、iPhone XS Max の対応が必須になりました。(参考: https://developer.apple.com/jp/app-store/submissions/)一般のアプリではXcode を10.1 以上にアップグレードするだけでよいことが多いのですが、私が保守を行っている1 年ほど前にreact native で開発されたアプリにおいて、iPhone XR およびiPhone XS Max でのデザインが崩れてしまいました。本記事では、それの原因および対応方法について説明します。

アプリの現状

開発環境およびライブラリのバージョンは以下の通りです。(これは実際にリリースされているアプリものとは異なります)
  • Xcode 10.1
  • react-native 0.53.3
  • react-navigation 2.0.4
アプリの現状を再現するために、以下のコードによりデザインが崩れることを確認しました。ヘッダが黄色、メインの部分が青色、アプリ外が赤色で表示されます。

 
// App.js
import React, { Component } from "react";
import { SafeAreaView, View, Dimensions } from "react-native";
import { createStackNavigator, Header } from "react-navigation";

const styles = {
  container: {
    flex: 1,
    backgroundColor: "blue"
  },
  outer: {
    flex: 1,
    backgroundColor: "red"
  },
  header: {
    backgroundColor: "yellow"
  } 
};

const ScreenA = () => (
  <SafeAreaView style={styles.outer}>
    <View style={styles.container} />
  </SafeAreaView>
);

const AppNavigator = createStackNavigator({ ScreenA }, {
    navigationOptions: { headerStyle: styles.header }
  }
);

export default AppNavigator;
左からiPhone 8, iPhone X, iPhone XR, iPhone XS Max です。iPhone XR およびiPhone XS Max においてヘッダの領域が狭いことがわかります。

 

表示崩れの原因

このヘッダはreact-navigation が表示しているものです。そこで、react-navigation を調査することで、react-navigation が利用しているreact-native-safe-area-view に問題があることがわかりました。react-native-safe-area-view では、iPhone X 等にあるノッチの対応をしているライブラリなのですが、react-navigation が2.15.0 より古いバージョンでは、iPhone XS Max の対応がされていないreact-native-safe-area-view が利用されています。つまり、react-native-safe-area-view のバージョンが古いことが原因でした。

解決方法

3つの解決方法が考えられます。
  1. react-navigation のバージョンアップを行う
  2. react-native-safe-area-view のバージョンアップを行う
  3. iPhone XR およびiPhone XS Max のときのみヘッダを拡張する
 

1 番目のreact-navigation のバージョンアップを行うのが一番正しい方法かと思います。ただし、react-navigation はバージョンアップによりAPI が変更されていることがあり、あまり工数を掛けずに保守をしたい場合には不適当かもしれません。

 
npm install react-navigation@2.15
2 番目のreact-native-safe-area-view のバージョンアップを行うのはとりあえずの対応方法ですが、工数を掛けずに問題を解決することが可能なことが多いです。

 
npm install react-native-safe-area-view@0.11
vi package-lock.json // react-navigation が依存しているreact-native-safe-area-view のバージョンを0.11.0 に変更
上記の対応を行うことで、下記のように修正されます。iPhone XR およびiPhone XS Max において適切にヘッダが表示されています。

 


 

3 番目のヘッダの領域を拡張を行うのは既存への影響が少ないですが、きれいに修正するのは難しいです。

 
// App.js
const isXsMax = (): boolean => {
  const { width, height } = Dimensions.get("window");
  if (width === 414 && height === 896) return true; // この条件は画面縦向きのみなので、横向きの場合も必要
  return false;
};

const AppNavigator = createStackNavigator({ ScreenA }, {
    navigationOptions: {
      headerStyle: [
        styles.header,
        isXsMax() && styles.xsmax_header, // ヘッダの領域を拡張させるスタイル
      ]
    }
  }
);
上記のようにiPhone XS Max であるということを判別する関数を用意して、iPhone XS Max の場合のみヘッダのスタイルを変更します。

さいごに

react-navigation の古いバージョンにおけるiPhone XS Max のデザイン崩れの原因および対応について説明しました。根本的にはreact-navigation のバージョンアップを行えばよいのですが、工数をできるだけ掛けないような対応方法について提案しました。

 

次世代システム研究室では、グループ全体のインテグレーションを支援してくれるアーキテクトを募集しています。インフラ設計、構築経験者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ募集職種一覧からご応募をお願いします。

皆さんのご応募をお待ちしています。

Pocket

関連記事