[iOS] [SwiftUI] [fastlane] UserInterfaceSizeClass の調査にシミュレータと fastlane を活用する

SwiftUI

     
⌛️ 2 min.
UIDevice を使うと、デバイスの情報が取れますが、どの機種がどのように返すのかを調べたくなります。

コツコツ調べるのも良いのですが、fastlane を使って、自動的に調べる方法を説明します。

背景

SwiftUI で画面をレイアウトしていると、スクリーンサイズによりレイアウトを調整したくなります。

毎年新しいモデルは発売されますが、画面サイズは同じであったり、微妙に変化していたりで一定の法則は見えません。

SwiftUI では、スクリーンサイズの大まかな情報を取得できるように Environment 変数として、horizontalSizeClass と verticalSizeClass が用意されています。

Apple のドキュメントは、こちらこちら

これを使って、調整することを SwiftUI 的には、推奨されている気がしますが、それぞれのデバイスでの値がわかりません。

# 例によって、Apple のドキュメントには、記載が無いです。

ですので、いろいろ調べて法則が見つかるかどうかを確認しました。

普通(?)に調べる

以下のようなコードを使うと、シミュレータで選んだデバイスでの情報を確認できます。

UserInterfaceSizeClass の確認

「UserInterfaceSizeClass の確認」
UserInterfaceSizeClass 確認用コード


//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2020/11/21
//  © 2020  SmallDeskSoftware
//

import SwiftUI

struct ContentView: View {
    @Environment(\.horizontalSizeClass) var horizontalSizeClass
    @Environment(\.verticalSizeClass) var verticalSizeClass
    var body: some View {
        VStack {
            Text( "Device: \(UIDevice.current.name)")
            Text("Horizontal:  \(sizeAsString(sizeClass: horizontalSizeClass))")
            Text("Vertical:  \(sizeAsString(sizeClass: verticalSizeClass))")
            }
        }

    func sizeAsString(sizeClass: UserInterfaceSizeClass?) -> String {
        if let sizeClass = sizeClass {
            switch sizeClass {
                case .compact:
                    return "Compact"
                case .regular:
                    return "Regular"
                default:
                    return "unknown"
            }
        }
        return "Unknown"
    }

}

fastlane を使って、調べよう

AppStore 登録用に画面のスナップショットを撮影している fastlane を使うことで、複数シミュレータを効率的に動作させられることに気づきました。

Fastlaneでスクリーンショット にフレームをつける Fastlaneでスクリーンショット にフレームをつける

fastlaneでiOSアプリをAppStoreへ登録できるまで(の最初の一歩で、スクリーンショットを作るまで) fastlaneでiOSアプリをAppStoreへ登録できるまで(の最初の一歩で、スクリーンショットを作るまで)

UIScreen サイズも調べました

以下のようなコードに修正して、UIScreen のサイズも合わせて調べることにしました。

ScreenSize もチェック

「ScreenSize もチェック」
example code


//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2020/11/21
//  © 2020  SmallDeskSoftware
//

import SwiftUI

struct ContentView: View {
    @Environment(\.horizontalSizeClass) var horizontalSizeClass
    @Environment(\.verticalSizeClass) var verticalSizeClass
    var body: some View {
        VStack {
            Text( "Device: \(UIDevice.current.name)")
            Text("UserIntefaceSizeClass")
            Text("Horizontal:  \(sizeAsString(sizeClass: horizontalSizeClass))")
            Text("Vertical:  \(sizeAsString(sizeClass: verticalSizeClass))")
            Text("UIScreen")
            Text("width: \(UIScreen.main.bounds.size.width, specifier: "%.0f")")
            Text("height: \(UIScreen.main.bounds.size.height, specifier: "%.0f")")
        }
    }
    
    func sizeAsString(sizeClass: UserInterfaceSizeClass?) -> String {
        if let sizeClass = sizeClass {
            switch sizeClass {
                case .compact:
                    return "Compact"
                case .regular:
                    return "Regular"
                default:
                    return "unknown"
            }
        }
        return "Unknown"
    }

}

調査対象デバイス

自分の環境で存在した以下のシミュレータを使ってチェックしました。

コード

devices([
  "iPhone 6s",
  "iPhone 8",
  "iPhone 8 Plus",
  "iPhone 11",
  "iPhone 11 Pro",
  "iPhone 11 Pro Max",
  "iPhone 12",
  "iPhone 12 Pro",
  "iPhone 12 Pro Max",
  "iPhone 12 mini",
  "iPhone SE (2nd generation)"
])

各デバイスでの horizontalSizeClass/verticalSizeClass/UIScreen.main.bounds.size

で、調べてみたところ、以下のようになりました

width, height は、それぞれ UIScreen.main.bounds.size.width, UIScreen.main.bounds.size.height を意味しています。

Portlait での値

デバイス名 horizontalSizeClass verticalSizeClass width height
iPhon 6s Compact Regular 375 667
iPhone 8 Compact Regular 375 667
iPhone 8 Plus Compact Regular 414 736
iPhone 11 Compact Regular 414 896
iPhone 11 Pro Compact Regular 375 812
iPhone 11 Pro Max Compact Regular 414 896
iPhone 12 Compact Regular 390 844
iPhone 12 Pro Compact Regular 390 844
iPhone 12 Pro Max Compact Regular 428 926
iPhone 12 mini Compact Regular 375 812
iPhone SE (2nd generation) Compact Regular 375 667

Landscape での値

デバイス名 horizontalSizeClass verticalSizeClass width height
iPhon 6s Compact Compact 667 375
iPhone 8 Compact Compact 667 375
iPhone 8 Plus Regular Compact 736 414
iPhone 11 Regular Compact 896 414
iPhone 11 Pro Compact Compact 812 375
iPhone 11 Pro Max Regular Compact 896 414
iPhone 12 Compact Compact 844 390
iPhone 12 Pro Compact Compact 844 390
iPhone 12 Pro Max Regular Compact 926 428
iPhone 12 mini Compact Compact 812 375
iPhone SE (2nd generation) Compact Compact 667 375

まとめ:UserIntafaceSizeClass とデバイスの関係

タイトル
  • デバイスと値との関係は表の通り
  • Compact と Regular の境界は、わかりません。
  • UI のバリエーションを作る時に、Compact/Regular で分けるのが効率的なのか不明です

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です