【Swift】Swift入門 ~ アプリのユニバーサル化をしてみる ~

2020.04.06

 

どうも、むつたくです。

今回は作成したiPhone向けアプリをiPadに対応させるためのユニバーサル化について紹介していきます。
iPhoneからiPadは画面サイズが全く異なり、フォントが小さすぎて見辛かったり、AutoLayoutが崩れたりと、四苦八苦してします。

 

しかし、そんな苦労を解消してくれるのが「SizeClasses」です!
デバイスの大きさによって、制約を有効・無効を切り替えることができる優れものなので是非とも覚えておきたいことの1つです。

 

前回までのSwift記事

【Swift】Swift入門 ~ UIPageViewControllerを使ってみる ~
【Swift】Swift入門 ~ presentの画面遷移 ~
【Swift】Swift入門 ~ NavigationControllerを使ってみる ~
【Swift】Swift入門 ~ UITableViewを使ってみる ~

 

合わせて読みたいUITableViewの記事

【Swift5】UITableViewの編集モード、スワイプアクションについてまとめてみた

 

今回やること

 

開発環境

  • macOS Catalina(10.15.3)
  • Xcode 11.3
  • Swift 5.1
  • Simulater iPhone 11Pro / iPad Air(3rd Gen)
  • iOS 13.2

 

SizeClasses について

SizeClassesは、[ iPhone / iPad ]の横縦サイズを抽象的なサイズである「Compact」、「Regular」、もしくは「Any(前述両サイズを指す)」に分類されます。
そして、それらサイズに対してAutoLayoutを指定できる仕組みにする…と言うことを担っています。使えると便利です。楽チンです。

 

デバイスを縦持ちとした場合、iPhoneは「横: Compact / 縦: Regular」に、iPadは「横: Regular / 縦: Regular」になっています。

 

まとめるとこんな感じ

デバイス 横サイズ 縦サイズ
iPhone 系 Compact Regular
iPad 系 Regular Regular

 

デバイスを横持ちとした場合、iPhoneは無印 & S系とPlus系に分類され、無印 & S系は「横: Compact / 縦: Compact」、Plus系は「横: Regular / 縦: Compact」になります。iPadの場合は、「横: Regular / 縦: Regular」なので、縦持ちと変わりません。
注意して頂きたいのが、iPhone11系です。無印 & ProMaxが「横: Regular / 縦: Compact」、Proが「横: Compact / 縦: Compact」になります。ちょっと異なるので、頭の片隅にでも入れといてください。

 

まとめるとこんな感じ

デバイス 横サイズ 縦サイズ
iPhone 無印 / S系 Compact Compact
iPhone Plus 系 Regular Compact
iPhone 11Pro Compact Compact
iPhone 11 / 11ProMax Regular Compact
iPad 系 Regular Regular

 

例としてあげてみます。端末は「iPhone11 Pro」です。上からImageView、Button、Buttonの順に配置され、制約も上から全て設定している状態です。
Buttonは、StackViewの中に入れてます。
一応それぞれのコントローラには高さの制約も設定してます。

 

 

 

この状態で実行すると、iPhone 11Proの場合はこんな感じになります。

 

普通ですね。
しかし、これをiPad Air 3genにすると…。

当たり前ですが、横いっぱいに広がりました。
それを回避するのが「SizeClasses」なので、設定してみました。ImageViewをいい感じの大きさに、Buttonを水平に並べて配置させます。
結果がこちら。

まともな?配置にできました。全てStoryBoardで設定しましたので、簡単にできます。
一応コードから設定できたり、SizeClassを上書きできたりしますが、今回はしません。全てStoryBoardから行います。
では、実際に設定してみましょう。

 

SizeClasses を設定する

SizeClassesをStoryBoardで設定する際、表記名がそれぞれのイニシャルを組み合わせたものになっています。
例えば、iPhone11Proの場合、「wC hR(width=Compact, height=Regular)」、
iPadだと「wR hR(width=Compact, height=Compact)」と言った感じになります。
確認は、エディタの左下でできます。

 

設定するSizeClassesは、「左右マージンの伸縮」、「ボタンの表示/非表示切り替え」です。

 

左右マージンのSizeClasses適用

まずは「左右マージンの伸縮」から紹介します。

  1. デバイスリストからiPhone 11Proを選択する
  2. ImageViewの制約「左右マージン」をクリック
  3. アトリビュート(属性)インスペクタをクリック
  4. インスペクタペイン一番下の「Constant」の左側に「+」ボタンがあるので、それをクリック
  5. iPhone用に、「width: Compact」、「height: Regular」を選択し、「Add Variation」をクリック
  6. iPad用に、「width: Regular」、「height: Regular」を選択し、「Add Variation」をクリック
  7. 「wRcR」を適切な値を入力(ここでは「100」を設定)
  8. デバイスをiPad系に変更し、Preview確認

 

これで、iPhone←→iPadを切り替えてもいい感じに中央に配置されているかと思います。
大事なのはNo.5No.6になります。この部分がSizeClassesを設定している箇所になり、これにより、デバイスによって制約を可変にしています。
他の制約も上記のような感じで設定していくことで、AutoLayoutが崩れないようになります。

 

制約を一個ずつ設定してくので、ちょっと手間はありますが、最初からiPhone・iPad対応のアプリを作成するのであれば、制約を設定していく時に同時にSizeClassesも設定するのが良いと思います。

 

ボタンの表示/非表示切り替え

次はSizeClassesを使用したボタンの表示/非表示を切り替える方法を紹介します。
ここでは、ボタンをStackViewに入れ、配置がiPhone 11Proでは縦並び、iPad Air 3Genでは横並びにするため、ボタンを複製し、表示の切り替えをします。

  1. デバイスリストからiPhone 11Proを選択する
  2. 「Button1」、「Button2」を選択する
  3. StackViewに縦並びで入れる
  4. 制約がリセットされるので、ImageViewまでの上マージン及び、左右マージンを再設定
  5. アトリビュート(属性)インスペクタをクリック
  6. 一番下「Installed」項目があり、その左隣に「+」ボタンがあるのでクリック
  7. iPhone用に、「width: Compact」、「height: Regular」を選択し、「Add Variation」をクリック
  8. iPad用に、「width: Regular」、「height: Regular」を選択し、「Add Variation」をクリック
  9. iPad用に追加した項目のチェックを外す
  10. No.4で追加した制約もNo.7-No.9と同様に設定する

 

ここまでがiPhone 11Proの設定になります。
大事なのはNo.7 ー No.9になります。「installed」のチェック次第でコントローラや制約の表示/非表示を切り替えることができます。

 

次はiPadの設定です。iPhoneと同じようなことをします。

  1. デバイスリストからiPad Pro 10.5を選択する(Air 3Genがないので…)
  2. 「Button1」、「Button2」を作成(もしくはコピぺ)する
  3. StackViewに横並びで入れる
  4. ImageViewまでの上マージン及び、左右マージンを再設定
  5. アトリビュート(属性)インスペクタをクリック
  6. 一番下「Installed」項目があり、その左隣に「+」ボタンがあるのでクリック
  7. iPhone用に、「width: Compact」、「height: Regular」を選択し、「Add Variation」をクリック
  8. iPad用に、「width: Regular」、「height: Regular」を選択し、「Add Variation」をクリック
  9. iPhone用に追加した項目のチェックを外す
  10. No.4で追加した制約もNo.7-No.9と同様に設定する

 

ここまでがiPadの設定になります。
大事なのはiPhone同様にNo.7 ー No.9になります。
installedのチェックを外し忘れた場合でも、Xcodeで警告を出してくれるので、その部分を修正してあげればOKです。

 

また今回は、StackViewを使用していたかつ、StoryBoardだけでの設定だったので、ボタンを複製していましたが、StackViewにせず、ボタンに係る制約全てにSizeClassesを設定すれば同じことを実現できます。

 

 


 

SizeClassesの使い方については以上になります。
それでは、またの機会に!


Top