UIをiPhone Xに対応する

問題点

iPhone Xは去年の11月に発売された最新のiPhoneです。今までのiPhoneと違いホームボタンがなく、画面が機体の全体に広がっているというのが大きな特徴です。この画面の大きさが今までの比率と違います。画面の上部にはカメラやセンサーがあるため欠けがあり、下にはホームインジケータというUIが表示されています。

縦に長くなった画面(2436×1125)により比率が16:9よりも細長くなります。このためにUIが崩れることがあります。

また画面上下部にUIを表示すると被ってしまい正しく表示できない問題が起こります。ここにボタンが出てしまうと押せなくなって致命的なこともあります。

対応する?

2018年4月以降に新しくアプリを出す場合は対応が必須となります。

こちらに提出についての説明があります。

Starting April 2018, all new iOS apps submitted to the App Store must be built with the iOS 11 SDK. All new apps for iPhone, including universal apps, must support the Super Retina display of iPhone X.

上のようにiPhone Xへの対応について書いてあります。

アップデートについては必須ではないようですが、いずれ必須になっていくでしょう。新しいアプリを出していく予定なので、今回対応方法について調べたわけです。

対応方法

セーフエリアという概念があります。これは画面の使える領域を表すものです。画面の隅が丸くなっているなどで全体が使えない場合にきちんと表示に使える領域を表すものです。セーフエリア内にUIを表示すればUIが消えたり、押せなくなったりすることはありません。

今回使ったUnityは2017.3.1f1 Personalです。Screen.safeAreaがサポートされていればなんでもいいと思います。

UnityからUIをなんとかするためのプロジェクトが提供されています。結構前のものなので、プラグインでセーフエリアを取るようになってました。(プロジェクトのAPIについての説明はここ)SetCanvasBounds.csがUIをうまいこと調整するための仕組みです。今はGetSafeArea()ではなくScreen.safeAreaにすればいいと思います。

SetCanvasBounds.csには2つのRectTransformのフィールドがあります。ひとつはcanvasでもうひとつはpanelです。canvasはスクリプト内で使われてないみたいですが、panelの方は全体のサイズを調整するためにつかっているUIのようです。panelのanchorMinとanchorMaxを画面の大きさに対するセーフエリアの大きさの比率にしています。panelの下に他のUIを置くようにして、panelを画面全体に広がるような範囲を持つように設定しておけばうまくいきます。

プロジェクトのTestシーンに入っているUIはこんな構造です。

このPanelのanchorMinとanchorMaxがスクリプトで変更されます。PC上ではsafeAreaがスクリーンサイズと同じなので以下のように表示されています。

ゲームビュー全体に広がったUIであり、4隅にテキストが表示されています。

GetSafeAreaの返す値を修正し、スクリーンより小さくしたものが以下の表示です。iPhone Xの横向き表示だと画面の左右と下がセーフエリアから外れるっぽいので、それを再現するように設定しています。Editor上でスクリプトの影響を確認するには小細工が必要でしたが、実機では正しいセーフエリアが返ってくるのでその必要はありません。