目次
Session概要
利用可能なSwiftUIビューを見つけ、Xcode Previewsのキャンバスへドラッグ&ドロップし、リッチで視覚的なアプリの編集を可能にするのがXcode Libraryです。自身のビューとモディファイアを使いXcode Libraryのコンテンツを拡大する方法、またアプリやSwiftパッケージ内で再利用性と発見性を最適化する方法について https://developer.apple.com/videos/play/wwdc2020/10649/
Xcode 12での新機能
- Xcode 12ではSwiftUIビューとモディファイアをXcode Libraryに追加可能
Xcode Libraryの利点
- 発見可能性
- Libraryは開発者が利用可能なビジュアルコンテンツを探す場所で、重要で再使用可能なビューを配置し見つけやすくする
- 習得しやすい
- 各アセットはコンパイル可能な形で提供され、特定のビューやモディファイアの用途をコードのユーザに示すのに役立つ
- ビジュアル編集
- キャンバスにドラッグ&ドロップでき、Libraryからビューやモディファイアの插入でXcode Previewsがレンダリングを継続しリッチなビジュアル編集を可能にする
- その他
- 明示的にビルドせずともプロジェクトが実行可能でない場合でもコンテンツをLibraryに与えられる
- Libraryコンテンツプロバイダコードは実行されないため、プロジェクトが配布用(release build)にビルドされた時、コンパイラが分離する
Xcode Libraryの拡張
- LibraryContentProviderプロトコルに準拠した新しいタイプを宣言する必要がある
- LibraryContentProviderプロトコルの要件
- views Xcode Libraryの拡張に使用できる viewsプロパティ を追加する
- モディファイアXcode Libraryの拡張に利用可能なモディファイアの関数 を追加する
public protocol LibraryContentProvider {
@LibraryContentBuilder
var views: [LibraryItem] { get }
@LibraryContentBuilder
public func modifiers(base: ModifierBase) -> [LibraryItem]
}
Libraryアイテムの作成方法
- Libraryアイテムの作成にXcodeが求める最小データはユーザがアイテムを取得した時に插入される補完(下記サンプルでいうと、SmoothieRowView)
LibraryItem(
SmoothieRowView(smoothie: .lemonberry),
visible: true, // 視認性
title: "Smoothie Row View", // Libraryで検索しやすい + わかりやすい命名が良い
category: .control // レイアウト、エフェクトなど
)

Libraryアイテムのカスタマイズオプション
同一のビューに相当した異なる設定の複数のLibraryアイテムの作成は合理的struct LibraryContent: LibraryContentProvider {
@LibraryContentBuilder
var views: [LibraryItem] {
LibraryItem(
SmoothieRowView(smoothie: .lemonberry),
category: .control
)
LibraryItem(
SmoothieRowView(smoothie: .lemonberry, showNearbyPopularity: true),
title: "Smoothie Row View With Popularity",
category: .control
)
}
}
モディファイアLibraryの作成
下記のサンプルコードでは、width, heightを取得してアスペクト比を保ちつつ、指定された画面いっぱいに表示するextension Image {
func resizedToFill(width: CGFloat, height: CGFloat) -> some View {
return self
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: width, height: height)
}
}
// 上記のImage Extension resizedToFillをモディファイアで使用するサンプル
@LibraryContentBuilder
func modifiers(base: Image) -> [LibraryItem] {
LibraryItem(
base.resizedToFill(width: 100.0, height: 100.0) // width, heightは補完部分
)
}