[Xcode] Xcode のプレビューの複数デバイスを表示する方法

Xcode の Preview で複数デバイスをまとめて表示する方法を説明します。

複数機種のプレビュー表示

少し前まで、プレビューはあくまでプレビューであり、デバイスごとの表示は、シミュレータを立ち上げる必要があると思ってました。

実は、Xcode 内のプレビューに対して、デバイスを指定する方法があります。さらに、複数のプレビューを表示することで、複数デバイス上でのプレビューを表示できます。

プレビューの仕組み

Xcode 上でプレビューが行われるのは以下の時です。

  • アクティブなファイル内に、PreviewProvider に準拠した struct が存在する

PreviewProvider は以下の2つの情報をプレビュー向けに保持しています。

  1. static var previews: Self.Previews
  2. static var platform: PreviewPlatform?

1つめの previews は、実装必須のプロパティです。このプロパティは、View に準拠していて、このビューがプレビューとして表示されます。

プレビュー向けの modifier

View protocol には、「Configuring Previews in Xcode」として、以下のような modifier が用意されています。

  • previewDevice
  • previewDisplayName
  • previewLayout
  • previewContext

.previewDevice

プレビュー時に使用されるスクリーンサイズを、デバイスを指定することで、指定できます。

使用できるデバイス名は、ターミナルで以下のコマンドを実行することで取得できます。

コード
% xcrun simctl list devicetypes
== Device Types ==
iPhone 4s (com.apple.CoreSimulator.SimDeviceType.iPhone-4s)
iPhone 5 (com.apple.CoreSimulator.SimDeviceType.iPhone-5)
iPhone 5s (com.apple.CoreSimulator.SimDeviceType.iPhone-5s)
iPhone 6 Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-6-Plus)
iPhone 6 (com.apple.CoreSimulator.SimDeviceType.iPhone-6)
iPhone 6s (com.apple.CoreSimulator.SimDeviceType.iPhone-6s)
iPhone 6s Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-6s-Plus)
iPhone SE (1st generation) (com.apple.CoreSimulator.SimDeviceType.iPhone-SE)
iPhone 7 (com.apple.CoreSimulator.SimDeviceType.iPhone-7)
iPhone 7 Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-7-Plus)
iPhone 8 (com.apple.CoreSimulator.SimDeviceType.iPhone-8)
iPhone 8 Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-8-Plus)
iPhone X (com.apple.CoreSimulator.SimDeviceType.iPhone-X)
iPhone Xs (com.apple.CoreSimulator.SimDeviceType.iPhone-XS)
iPhone Xs Max (com.apple.CoreSimulator.SimDeviceType.iPhone-XS-Max)
iPhone Xʀ (com.apple.CoreSimulator.SimDeviceType.iPhone-XR)
iPhone 11 (com.apple.CoreSimulator.SimDeviceType.iPhone-11)
iPhone 11 Pro (com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro)
iPhone 11 Pro Max (com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro-Max)
iPhone SE (2nd generation) (com.apple.CoreSimulator.SimDeviceType.iPhone-SE--2nd-generation-)
iPhone 12 mini (com.apple.CoreSimulator.SimDeviceType.iPhone-12-mini)
iPhone 12 (com.apple.CoreSimulator.SimDeviceType.iPhone-12)
iPhone 12 Pro (com.apple.CoreSimulator.SimDeviceType.iPhone-12-Pro)
iPhone 12 Pro Max (com.apple.CoreSimulator.SimDeviceType.iPhone-12-Pro-Max)
iPod touch (7th generation) (com.apple.CoreSimulator.SimDeviceType.iPod-touch--7th-generation-)
iPad 2 (com.apple.CoreSimulator.SimDeviceType.iPad-2)
iPad Retina (com.apple.CoreSimulator.SimDeviceType.iPad-Retina)
iPad Air (com.apple.CoreSimulator.SimDeviceType.iPad-Air)
iPad mini 2 (com.apple.CoreSimulator.SimDeviceType.iPad-mini-2)
iPad mini 3 (com.apple.CoreSimulator.SimDeviceType.iPad-mini-3)
iPad mini 4 (com.apple.CoreSimulator.SimDeviceType.iPad-mini-4)
iPad Air 2 (com.apple.CoreSimulator.SimDeviceType.iPad-Air-2)
iPad Pro (9.7-inch) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--9-7-inch-)
iPad Pro (12.9-inch) (1st generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro)
iPad (5th generation) (com.apple.CoreSimulator.SimDeviceType.iPad--5th-generation-)
iPad Pro (12.9-inch) (2nd generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--12-9-inch---2nd-generation-)
iPad Pro (10.5-inch) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--10-5-inch-)
iPad (6th generation) (com.apple.CoreSimulator.SimDeviceType.iPad--6th-generation-)
iPad (7th generation) (com.apple.CoreSimulator.SimDeviceType.iPad--7th-generation-)
iPad Pro (11-inch) (1st generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--11-inch-)
iPad Pro (12.9-inch) (3rd generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--12-9-inch---3rd-generation-)
iPad Pro (11-inch) (2nd generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--11-inch---2nd-generation-)
iPad Pro (12.9-inch) (4th generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--12-9-inch---4th-generation-)
iPad mini (5th generation) (com.apple.CoreSimulator.SimDeviceType.iPad-mini--5th-generation-)
iPad Air (3rd generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Air--3rd-generation-)
iPad (8th generation) (com.apple.CoreSimulator.SimDeviceType.iPad--8th-generation-)
iPad Air (4th generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Air--4th-generation-)
Apple TV (com.apple.CoreSimulator.SimDeviceType.Apple-TV-1080p)
Apple TV 4K (com.apple.CoreSimulator.SimDeviceType.Apple-TV-4K-4K)
Apple TV 4K (at 1080p) (com.apple.CoreSimulator.SimDeviceType.Apple-TV-4K-1080p)
Apple Watch - 38mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-38mm)
Apple Watch - 42mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-42mm)
Apple Watch Series 2 - 38mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-2-38mm)
Apple Watch Series 2 - 42mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-2-42mm)
Apple Watch Series 3 - 38mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-3-38mm)
Apple Watch Series 3 - 42mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-3-42mm)
Apple Watch Series 4 - 40mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-4-40mm)
Apple Watch Series 4 - 44mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-4-44mm)
Apple Watch Series 5 - 40mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-5-40mm)
Apple Watch Series 5 - 44mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-5-44mm)
Apple Watch SE - 40mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-SE-40mm)
Apple Watch SE - 44mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-SE-44mm)
Apple Watch Series 6 - 40mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-6-40mm)
Apple Watch Series 6 - 44mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-6-44mm)

上記は、2020.12 時点での macOS Catalina 10.15.7 + Xcode12.2 で取得できたリストです。

上記を参照して「iPhone 11」や「Apple Watch Series 5 - 44mm」 のように指定できることになります。

# 具体的には、(com.apple.... の手前までの文字列が使用できるようです。

previewDisplayName

プレビュー表示されるときのタイトルを指定することができます。

previewLayout

previewDevice から指定されるレイアウト(サイズ)を上書きすることができます。
デバイスで指定することもできますし、サイズ(縦横)を直接指定することもできます。

そのほかに、プレビューで必要となるサイズに合わせることもできるようです(未確認)

previewContext

キー・バリューを設定することができるようです。

現時点で何に使うか想像できていませんが、なにか有用な使い道があるのでしょう。

複数のプレビューを同時に表示する

ここまでで、特定のデバイスでのプレビューを表示することはできるようになりました。

次に、複数のプレビューを同時に表示させる方法を説明します。

複数の方法があります。

static var previews から複数ビューを返す

Static var previews から複数のビューを返すと、それぞれをプレビューに表示することができます。

previews から複数ビューを返す

//
//  PreviewManyViews.swift
//
//  Created by : Tomoaki Yagishita on 2020/12/06
//  © 2020  SmallDeskSoftware
//
import SwiftUI

struct iPhonePreviews: PreviewProvider {
    static var previews: some View {
        Text("Hello")
            .previewDisplayName("iPhone 11")
            .previewDevice(PreviewDevice(rawValue: "iPhone 11"))
        Text("Hello")
            .previewDisplayName("iPhone 6s")
            .previewDevice(PreviewDevice(rawValue: "iPhone 6s"))
    }
}

previewsが複数View返す

「複数View を返す previews を使った複数プレビュー」

複数の PreviewProvider を用意する

Xcode は、1ファイル内からでも複数の PreviewProvider を検知します。

複数の PreviewProvider に準拠した struct を定義すると複数のプレビューが表示されるようになります。

複数の PreviewProvider を定義

//
//  MyStruct.swift
//
//  Created by : Tomoaki Yagishita on 2020/12/06
//  © 2020  SmallDeskSoftware
//

import Foundation
import SwiftUI

struct iPhone11Preview: PreviewProvider {
    static var previews: some View {
        Text("Hello")
            .previewDisplayName("iPhone 11")
            .previewDevice(PreviewDevice(rawValue: "iPhone 11"))
    }
}

struct iPhone6sPreview: PreviewProvider {
    static var previews: some View {
        Text("Hello")
            .previewDisplayName("iPhone 6s")
            .previewDevice(PreviewDevice(rawValue: "iPhone 6s"))
    }
}

複数のPreviewProvider を使った複数プレビュー

「複数のPreviewProvider を使った複数プレビュー」

まとめ:デバイスプレビューの複数表示

デバイスプレビューの複数表示の方法
  • デバイス指定方法:previewDevice modifier を使って指定する
  • 複数表示方法1:static var prviews が複数 View を返すようにする
  • 複数表示方法2:PreviewProvider protocol に沿った struct を複数定義する

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

コメントを残す

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