コツコツ調べるのも良いのですが、fastlane を使って、自動的に調べる方法を説明します。
Sponsor Link
背景
SwiftUI で画面をレイアウトしていると、スクリーンサイズによりレイアウトを調整したくなります。
毎年新しいモデルは発売されますが、画面サイズは同じであったり、微妙に変化していたりで一定の法則は見えません。
SwiftUI では、スクリーンサイズの大まかな情報を取得できるように Environment 変数として、horizontalSizeClass と verticalSizeClass が用意されています。
これを使って、調整することを SwiftUI 的には、推奨されている気がしますが、それぞれのデバイスでの値がわかりません。
# 例によって、Apple のドキュメントには、記載が無いです。
ですので、いろいろ調べて法則が見つかるかどうかを確認しました。
普通(?)に調べる
以下のようなコードを使うと、シミュレータで選んだデバイスでの情報を確認できます。
//
// 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でiOSアプリをAppStoreへ登録できるまで(の最初の一歩で、スクリーンショットを作るまで)
UIScreen サイズも調べました
以下のようなコードに修正して、UIScreen のサイズも合わせて調べることにしました。
//
// 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 で分けるのが効率的なのか不明です
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
Sponsor Link