Xcode で Canvas を上手に利用するための Tips


記事内容

Xcode 12 では Canvas の機能を使って、コーディングしながらリアルタイムにデバイスの画面がどのように表示されるのかを確認できます。

この記事では、その便利な Canvas をさらにより良く使いこなすための Tips(ヒント)を掲載します。良い Tips があれば随時追加していく予定です。

もくじ

  • @EnvironmentObjectのプロパティを持つViewを表示するには
  • @Bindingのプロパティを持つViewを表示するには
  • Viewを必要最低限のサイズで表示するには
  • 複数デバイスのPreviewを表示するには ・・・2020/12/06追加
  • ライトモード、ダークモードを指定して表示するには・・・2020/12/13追加

@EnvironmentObjectのプロパティを持つViewを表示するには

ObservableObject クラス内の @Published 付きプロパティの値を 他のView から常に参照するために、そのクラスのインスタンスを @EnvironmentObject プロパティラッパーをつけて View 内に作成している場合、そのViewのプレビューには、以下のようにViewのインスタンスに、.environmentObject(ClassName())モディファイアをつける必要があります。これをつけないと Resume ボタンをクリックしても Canvas に表示されず、エラーになります。

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environmentObject(Manager())
    }
}

@Bindingのプロパティを持つViewを表示するには

@Bindingプロパティラッパーが付いているプロパティを持つ構造体の場合、そのプロパティはデータ型だけ指定され、値は代入されていません。例えば以下のように。

@Binding var name: String

このようなプロパティを持つ構造体のプレビューをCanvasに表示したい時、イニシャライズ時に適当な引数を入れてもエラーになります。このような場合は以下のように、引数として.constant()を指定するとうまく表示されます。これはView内のあらゆるバインディングで、何か値を仮に入れたい場合に使えます。プレビューのコードは以下のようになります。

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(name: .constant("Hoge Fuga"))
    }
}

Paul Hudson さんの Hacking with Swift もご参照ください。
https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-constant-bindings

Viewを必要最低限のサイズで表示するには

メインのViewに配置するコンポーネント用のView(画面のパーツ)を作成している場合、コンポーネント用のView単体をデバイススクリーン大のCanvasに表示するより、そのコンポーネント用Viewのみをジャストサイズで表示したい場合は、以下のように .previewLayout(.sizeThatFits) モディファイアをつけるとViewのジャストサイズになります。

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environmentObject(Manager())
            .previewLayout(.sizeThatFits)
    }
}

複数のデバイスモデルのPreviewを表示するには

Canvas に複数のデバイスモデル(例えば、iPhone 12 mini と iPhone 12 Pro と iPhone 12 Pro Maxなど)を同時に表示させたい場合、ForEachを利用しつつ、特定のモディファイアを表示したいViewにつけてあげると良いです。

追加すべきモディファイアは以下の2つです。

.previewDevice()
.previewDisplayName()

実際のコードは以下のようになります。


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ForEach(["iPhone 12 Pro", "iPhone 12 mini", "iPhone 12 Pro Max", "iPhone 8", "iPod touch (7th generation)"], id: \.self) { deviceName in
            ContentView()
                .previewDevice(PreviewDevice(rawValue: deviceName))
                .previewDisplayName(deviceName)
        }
    }
}

ライトモード、ダークモードを指定して表示するには

以下のモディファイアと引数(.light / .dark)を指定してあげるとライトモードもしくはダークモードを指定してCanvasにプレビューを表示できます。

.environment(\.colorScheme, .light)
.environment(\.colorScheme, .light)

プレビューの全体のコードは以下のようになります。

struct ContentView_Previews: PreviewProvider {
   static var previews: some View {
      Group {
         ContentView()
            .environment(\.colorScheme, .light)

         ContentView()
           .environment(\.colorScheme, .light)
   }
}