LoginSignup
3
2

More than 3 years have passed since last update.

【iOS】コードから端末のSizeClassを判断する(Swift)

Posted at

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パターンすべてを判定するロジックを載せておきます。

ViewController.swift
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にこちらをコピペしていただくだけでも動くと思います。
読んでいただいた方のお役に立てれば幸いです。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2