SizeClassとは
SizeClassとは、端末の縦横のサイズをそれぞれCompact
またはRegular
として指定し、その組み合わせによってレイアウトの変更ができるようにするための機能。
Compact
が小さいサイズのときに使われ、Regular
が大きいサイズとして使われます。
組み合わせは全部で4通りあります。
SizeClass(Full) | SizeClass(略) | 主な機種 |
---|---|---|
Compact/Compact | CC | iPhone8の横画面、iPhone12の横画面 |
Compact/Regular | CR | すべてのiPhoneの縦画面 |
Regular/Compact | RC | iPhone8Plusの横画面、iPhone11の横画面など |
Regular/Regular | RR | iPad(フルスクリーン)の縦画面、横画面 |
より詳しいパターンについては、公式ドキュメントをご参照ください。
https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/adaptivity-and-layout/
どうやって使うの?
StoryBoardから使う
簡単に説明すると、
SizeClassによって、制約を有効にしたり、Viewの表示非表示を切り替えることができます。
例1)ImageViewの高さを、SizeClassが「RR」のときは100px、「CR」のときは、60pxにするといったようなことができる。
例2)LabelをSizeClassが「RR」のときは非表示、「CR」のときは表示するといったようなことができる。
詳しい使い方については、下記の記事がわかりやすいと思いましたので、リンクを貼らせていただきます。
https://qiita.com/wnstjd0333/items/1c2ed3cec565f69cbb90
コードで使う
「UITraitEnvironment」プロトコルを実装しているクラスにおいて、traitCollection
プロパティが利用可能です。
代表例として、UIViewControllerは「UITraitEnvironment」プロトコルを採用しているため、traitCollection
が利用できます。
また、端末の回転やマルチタスキングへの切替によって、端末のSizeClassに変化があった場合、
traitCollectionDidChange(_:)
というメソッドが呼び出されます。(viewWillTransition(to:with:)
も呼ばれます。)
実際に使用したい場合は、どちらかのメソッドをオーバーライドして個々のViewControllerで利用していく感じです。
それらを活用して、現在の画面が、4パターンあるSizeClassのうちどれに当てはまるかをコード上から検知することができます。
この記事は、タイトルにもあるように、SizeClassの判断をコードで行うことが目的ですので、以下に書いていきます。
SizeClassパターンの検知
おそらく、マルチデバイス対応、マルチタスキング対応を実施しようとするとすべてのパターンが必要になると思いますので、4パターンすべてを判定するロジックを載せておきます。
enum SizeClass: String {
// width/height
case CC = "Compact/Compact"
case CR = "Compact/Regular"
case RC = "Regular/Compact"
case RR = "Regular/Regular"
}
class ViewController: UIViewController {
// 色々と省略
// viewWillTransitionでも代用可能です。previousTraitCollectionを使いたければ、traitCollectionDidChangeのが最適
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
// SizeClassが変わった時に呼ばれるので毎回チェックしたい場合は、ここでチェックするメソッドを呼び出す。
let sizeClass: String = returnSizeClass().rawValue
print(sizeClass)
// SizeClassが変わった時に、処理を書きたい場合はここに書く
}
func returnSizeClass() -> SizeClass {
if traitCollection.horizontalSizeClass == .regular
&& traitCollection.verticalSizeClass == .regular {
return .RR
} else if traitCollection.horizontalSizeClass == .regular {
return .RC
} else if traitCollection.verticalSizeClass == .regular {
return .CR
} else {
return .CC
}
}
}
enumで4パターンを定義しておいて、画面の状態によって当てはまるSizeClassをリターンするという方法で実装しました。
おそらく、ご自身のViewControllerにこちらをコピペしていただくだけでも動くと思います。
読んでいただいた方のお役に立てれば幸いです。