スプラッシュを一枚絵の画像にしている場合のiPhone XS Max，iPhone XRの最適化対応

## はじめに
iPhone XS Max 使っていて感じる違和感。
なんか iPhone X を拡大して表示されているだけに見えるアプリがある。
Xcode 10 でビルドされていないから最適化されていないのだけれども，
Xcode 10 でビルドしても変わらない場合があった。
そういえば 4.0 インチや 4.7・5.5 インチが追加されたときも同じことあったな・・・

スプラッシュ部分を `LaunchScreen.storyboard` などではなく，
Assets で設定した一枚絵の画像を使っている場合が上記に該当します。

## Xcode 10 での LaunchImage

__※ プロジェクトの問題で画像自体は削除しています。__

Xcode 9 の LaunchImage の例。

![xcode9_launchImage.png](https://qiita-image-store.s3.amazonaws.com/0/88266/3b0e635f-b01b-9a04-4e1a-94c8a5272144.png "xcode9_launchImage.png")


このプロジェクトをXcode 10 で見てみた際の例が下記で
iPhone X / iPhone XS までは適用できていた。
そしてなぜか iOS 8.0 and Later の方のチェックが外されてた。

![xcode9->10_launchImage.png](https://qiita-image-store.s3.amazonaws.com/0/88266/587f3451-c980-9671-4d96-0812f26d7e2a.png "xcode9->10_launchImage.png")


チェックを入れると iPhone XS Max，iPhone XR の項目が登場した。

![xcode9->10_2launchimage.png](https://qiita-image-store.s3.amazonaws.com/0/88266/1ca4ae2e-352a-7ec7-da40-47e2269570fb.png "xcode9->10_2launchimage.png")


最適化するためにこの部分に iPhone XS Max，iPhone XR 用の
サイズの LaunchImage をそれぞれ追加する必要があります。

画像のサイズは下記の通りです。
詳しくは Human Interface Guidelines[^1]を参照してください。

|端末名|サイズ(ピクセル)|
|:--|:--|
|iPhone XS Max|1242px × 2688px|
|iPhone XR|828px × 1792px|

ちゃんと最適化できたかどうかは黒帯とか出てないし分かりづらいけど，
サイレントスイッチの少し上あたりに NavigationBar の最下部が来ていたら
最適化されていて，少し下にあるとまだ対応していないかなって感じ。

アプリアイコンに関しては今回は対応不要みたい。

## コードで LaunchImage たちを取得

対応がこれで十分でなく，スプラッシュ表示を延長する部分があり，
各端末サイズの画像を取得して表示させていたコードがあった。
よって Assets で設定した LaunchImage をコードで取得する際の画像名を調べた。
とりあえず，ポートレートのみ。

|端末サイズ|スケール|画像名|
|:--:|:--:|:--|
|3.5inch|＠2x|LaunchImage-700@2x.png|
|4.0inch|＠2x|LaunchImage-700-568h@2x.png|
|4.7inch|＠2x|LaunchImage-800-667h@2x.png|
|5.5inch|＠3x|LaunchImage-800-Portrait-736h@3x.png|
|5.8inch|＠3x|LaunchImage-1100-Portrait-2436h@3x.png|
|6.1inch|＠2x|LaunchImage-1200-Portrait-1792h@2x.png|
|6.5inch|＠3x|LaunchImage-1200-Portrait-2688h@3x.png|

iPhone XR は @2x，iPhone XS Max が @3x の関係なので
scale を取得して判断材料にする必要がある。Swift は省略します。

```objc
NSString *launchImage;

CGRect mainFrame = [UIScreen mainScreen].bounds;
CGFloat scale = [UIScreen mainScreen].scale;  // 1 or 2 or 3
if (CGRectGetHeight(mainFrame) >= 896 && scale == 3.0) {
    // iPhone (6.5inch)
    launchImage = @"LaunchImage-1200-Portrait-2688h";
} else if (CGRectGetHeight(mainFrame) >= 896 && scale == 2.0) {
    // iPhone (6.1inch)
    launchImage = @"LaunchImage-1200-Portrait-1792h";
} else if (CGRectGetHeight(mainFrame) >= 812) {
    // iPhone (5.8inch)
    launchImage = @"LaunchImage-1100-Portrait-2436h";
} else if (CGRectGetHeight(mainFrame) >= 736) {
    // iPhone (5.5inch)
    launchImage = @"LaunchImage-800-Portrait-736h";
} else if (CGRectGetHeight(mainFrame) >= 667) {
    // iPhone (4.7inch)
    launchImage = @"LaunchImage-800-667h";
} else if(CGRectGetHeight(mainFrame) >= 568){
    // iPhone (4.0inch)
    launchImage = @"LaunchImage-700-568h";
} else {
    // iPhone (3.5inch)
    launchImage = @"LaunchImage-700";
}
```

2018-10-01 追記

### [注意]🚨2020年4月からリジェクト対象になります🚨[注意]

WWDC19 のセッションで 2020年4月より SplashImage のみを
使っているアプリはリジェクト対象になる旨が発表されました。

![Launch Storyboards.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88266/67178cc4-cc9b-4cd5-417c-47c9249db41b.png)

該当セッションは **Modernizing Your UI for iOS 13** です。序盤の方です。
[https://developer.apple.com/videos/play/wwdc2019/224/](https://developer.apple.com/videos/play/wwdc2019/224/)

`LaunchScreen.storyboard` の方を使うようにしましょう。
ダークモード対応もやりやすいはずです。(teratail で回答しましたー)

[https://teratail.com/questions/224110](https://teratail.com/questions/224110)

**2019-11-19 再追記**

## おわりに

個人アプリだとスプラッシュ画面は一枚絵の画像ではなくて，
さすがに `LaunchScreen.storyboard` 使っていますが，
業務で触っているのは，一枚絵使っているプロジェクトが
まだまだあったりするので備忘録として書きました。

ご覧いただきありがとうございました！


[^1]: https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/launch-screen/