ハイライト
Xcode 12 の「Optimize Interface for Mac」により、Mac Catalyst アプリが Mac イディオムで起動できるようになり、UIKit と SwiftUI は 1:1 ポイント サイズ、Mac コントロール スキン、Mac テキスト サイズ、およびシステム間隔を採用します。
主要内容
iPad アプリを Mac に導入する場合、多くの場合、最初のステップは「iPad に合わせてインターフェイスを調整する」を選択することです。このパスには互換性があり、UIKit は iPad のレイアウトを維持しようとします。コストも明らかです。インターフェイスは 77% 拡大縮小され、100 ポイントのコード サイズは画面上で 77 ポイントになり、テキストと画像も拡大縮小されます。
次のステップは「Mac 向けインターフェイスの最適化」です。アプリが起動時に Mac イディオムに入るのは、Xcode 12 のビルド設定です。この選択はコンパイル時には影響しませんが、ランタイム インターフェイスのメトリックは変更されます。コンテンツは 1:1 ポイントでレンダリングされ、システム ボタン、スライダー、スイッチ、およびアクティビティ インジケーターは Mac の外観を採用し、本文テキストは iPad の 17 ポイントから Mac の 13 ポイントに変更され、自動レイアウトのシステム間隔も Mac の間隔に変更されます。
これにより生じるワークロードは、レイアウトの監査に重点が置かれます。ハードコーディングされたフォントは、Mac のテキスト サイズに自動的に変更されません。コントロールの元のサイズに依存する制約は、新しいコントロールの測定値の影響を受けます。ユニバーサル アセットのみが提供されている場合、画像は Mac Scaled、iPad、そして Universal にフォールバックします。セッションはクックブック アプリを使用してこの移行パスを実証しました。セルの高さの変更、Mac アセットの提供、ナビゲーション バーの非表示、Mac イディオムの特性バリエーションを使用して下部の [保存] ボタンと [キャンセル] ボタンをインストールしました。
SwiftUI の移行コストが低くなります。 GroupBox、Toggle、Button、および Picker は、Mac の慣用に従って Mac スタイルに変更されます。カスタマイズされた ButtonStyle はシステムによって置き換えられません。このセッションでは、UIHostingController を使用して SwiftUI ビューを UIKit アプリに組み込む方法も紹介されました。 GroupBox、Toggle、および Picker は、最適化後に Mac のパフォーマンスを自動的に取得します。
##詳細
1. Mac のイディオムを使用して、最適化された Catalyst ランタイムを区別します。
(29:33)
「Mac 向けインターフェイスの最適化」は、新しいビルド ターゲットと同等ではありません。 Session は、この設定がコンパイル時間に影響を与えないと明示的に述べています。最適化されたランタイムを決定するには、「traitCollection.userInterfaceIdiom == .mac」を使用する必要があります。 Mac Catalyst 環境でコンパイルされているかどうかを判断するには、targetEnvironment(macCatalyst) を使用します。
// Idiom vs conditional compilation block
if traitCollection.userInterfaceIdiom == .mac {
// "Optimize Interface for Mac" specific code
}
#if targetEnvironment(macCatalyst)
// Mac Catalyst specific code
#endif
if traitCollection.userInterfaceIdiom == .mac {
// "Optimize Interface for Mac" specific code
} else if traitCollection.userInterfaceIdiom == .pad {
#if targetEnvironment(macCatalyst)
// Mac Catalyst specific code
#else
// iPad specific code
#endif
}
キーポイント:
traitCollection.userInterfaceIdiom == .macは、最適化された Mac イディオムに対応します。#if targetEnvironment(macCatalyst)はコンパイル環境に相当し、イディオムと同レベルの判定ではありません。- 最後の段落では、Mac イディオム、Catalyst での iPad イディオム、および通常の iPad の 3 つのパスが分離されており、バック デプロイ時の差異の処理に適しています。
2. UIKit レイアウトを移行するときは、最初にナビゲーション バーとハードコーディングされたディメンションを処理します。
(22:04)
クックブック アプリの [新しいレシピ] ウィンドウでは、iPad スタイルのナビゲーション バーが Mac ウィンドウの上部に表示されます。セッションを処理する方法は非常に簡単です。Mac のイディオムの下にあるナビゲーション バーを非表示にし、[保存] と [キャンセル] を一番下のビューに移動します。また、動的テキスト スタイルはプラットフォームに応じて調整されますが、ハードコードされたフォントは調整されないため、ラベルが 17 ポイントのシステム フォントで修正されます。
if traitCollection.userInterfaceIdiom == .mac {
navigationController?.setNavigationBarHidden(true, animated: false)
}
キーポイント:
traitCollection.userInterfaceIdiomは実行時の判断であり、Catalyst コードの同じセットに配置するのに適しています。.macブランチは、Mac のイディオムでのインターフェイスの違いのみを処理します。setNavigationBarHidden(true,animate:false)は、セッション内のナビゲーション バーを削除するステップに対応します。
(24:47)
Interface Builder には、Mac イディオムの特性バリエーションもあります。セッションで、[保存] と [キャンセル] を含むスタック ビューを Mac イディオムにのみインストールされるように設定し、元の最下位制約の優先順位を [必須] から [高] に下げます。このようにして、iPad は元のレイアウトを維持し、Mac は下部のボタンのためのスペースを残します。
3. SwiftUI コントロールは Mac の慣用に従って外観を変更します
(31:26)
SwiftUI の GroupBox は、Mac 用に最適化された場合に Mac GroupBox をレンダリングします。 Session は、ネストされた GroupBox を使用して構造化コンテンツを表示し、システムは背景とパディングをさまざまなレベルに割り当てます。
// Nested GroupBoxes
struct ContentView: View {
var body: some View {
GroupBox {
VStack {
Text("High level information")
GroupBox {
Text("Some elaborate details")
}
}
}
}
}
キーポイント:
- 外側の
GroupBoxは、構造化されたコンテンツのセットを表します。 VStackは、グループ内で垂直方向のコンテンツを整理します。- 内側の
GroupBoxには、より詳細な情報が表示されます。 Mac 用に最適化すると、Mac GroupBox の視覚的な階層が使用されます。
(32:00)
トグルのデフォルトの外観も変更されます。 iPadOS のデフォルトはスライド スイッチ、Mac のデフォルトはチェックボックスです。 Session では、デフォルトのスタイルが適切でない場合は、ToggleStyle 構造体と ToggleStyle 修飾子を使用してスタイルを指定できることも説明しています。
// DefaultToggleStyle
struct ContentView: View {
@State var completed: Bool = false
var body: some View {
Toggle("Complete?", isOn: $completed)
}
}
キーポイント:
@State var completedToggle のブール状態を保存します。Toggle("Complete?", isOn: $completed)はデフォルトの ToggleStyle を使用します。- デフォルトのスタイルは、Mac の慣用に従ってチェックボックスとして表示されます。
(33:14)
ピッカーは Mac イディオムで Mac ピッカーを使用します。 Session の例では、整数タグを使用して、Small、Medium、Large の 3 つのオプションをバインドします。
// DefaultPickerStyle
struct ContentView: View {
@State var sizeIndex = 2
var body: some View {
Picker("Size:", selection: $sizeIndex) {
Text("Small").tag(1)
Text("Medium").tag(2)
Text("Large").tag(3)
}
}
}
キーポイント:
@State var sizeIndex = 2により、Medium が最初の選択肢になります。Picker("Size:",selection: $sizeIndex)はコントロールを状態にバインドします。- 各
Text(...).tag(...)はオプションの値を提供し、Mac イディオムでは Mac ユーザーに馴染みのある選択コントロールが表示されます。
4. カスタマイズされたボタンのスタイルは保持されます
(33:55)
システムボタンはMacのような外観になります。カスタム ButtonStyle は Catalyst によってオーバーライドされません。セッションはカスタム グラデーション ボタンで示されており、SwiftUI と Catalyst はカスタム本文をそのまま残します。
// Custom gradient button
struct CustomNinetiesButtonStyle: ButtonStyle {
var angle: Angle = .degrees(54.95)
func gradient(shifted: Bool) -> AngularGradient {
let lightTeal = Color(#colorLiteral(red: 0.2785285413, green: 0.9299042821, blue: 0.9448828101, alpha: 1))
let yellow = Color(#colorLiteral(red: 0.9300076365, green: 0.8226149678, blue: 0.59575665, alpha: 1))
let pink = Color(#colorLiteral(red: 0.9437599778, green: 0.3392140865, blue: 0.8994731307, alpha: 1))
let purple = Color(#colorLiteral(red: 0.5234025717, green: 0.3247769475, blue: 0.9921132922, alpha: 1))
let softBlue = Color(#colorLiteral(red: 0.137432307, green: 0.5998355746, blue: 0.9898411632, alpha: 1))
let gradient = Gradient(stops:
[.init(color:lightTeal, location: 0.2),
.init(color: softBlue, location: 0.4),
.init(color: purple, location: 0.6),
.init(color: pink, location: 0.8),
.init(color: yellow, location: 1.0)])
return AngularGradient(gradient: gradient, center: .init(x: 0.25, y: 0.55), angle: shifted ? angle : .zero)
}
func makeBody(configuration: ButtonStyleConfiguration) -> some View {
let background = NinetiesBackground(isPressed: configuration.isPressed,
pressedGradient: gradient(shifted: false),
unpressedGradient: gradient(shifted: true))
return configuration.label
.foregroundColor(configuration.isPressed ? Color.pink : Color.white)
.modifier(background)
}
struct NinetiesBackground: ViewModifier {
let isPressed: Bool
let pressedGradient: AngularGradient
let unpressedGradient: AngularGradient
func body(content: Content) -> some View {
let foreground = content
.padding(.horizontal, 24)
.padding(.vertical, 14)
.foregroundColor(.white)
return foreground
.background(Capsule().fill(isPressed ? pressedGradient : unpressedGradient))
}
}
}
struct ContentView: View {
var body: some View {
Button("Awesome", action: {})
.buttonStyle(CustomNinetiesButtonStyle())
}
}
キーポイント:
CustomNinetiesButtonStyleはButtonStyleを実装し、スタイル ロジックは開発者によって制御されます。configuration.isPressedは押された状態に基づいて色と背景を切り替えます。.buttonStyle(CustomNinetiesButtonStyle())はカスタム スタイルを明示的に適用します。Catalyst はそれをシステムの Mac ボタンに置き換えません。
重要ポイント
1. Catalyst レイアウト監査パネルを作成する
- やるべきこと: Mac のイディオムでチェックする必要があるアプリ内のビューをリストします: ハードコーディングされたフォント、固定サイズの画像、コントロールの元のサイズに依存する制約、システム間隔の変更。
- 実行する価値がある理由: Mac 用に最適化されたセッション表示では、代わりに 1:1 ポイント、Mac コントロール測定、および Mac テキスト サイズが使用されます。シンプルなビューには改行が含まれ、画像が大きくなり、スライダーが狭くなる場合もあります。
- 開始方法: まず、Mac イディオム ブランチでキー ビュー コントローラーをマークし、次に
traitCollection.userInterfaceIdiom == .macの下のレイアウトの違いを 1 つずつ確認します。
2. よく使用される写真の完全な Mac アセット
- 対処方法: リストアイコン、お気に入りアイコン、地図アノテーションなどの高頻度画像を Mac 版に追加します。
- 実行する価値がある理由: Mac 用に最適化すると Mac アセットが優先されるとセッションで説明されています。見つからない場合は、Mac Scaled、iPad、Universal に戻り、サイズが適切でない可能性があります。
- 開始方法: アセット カタログのデバイス インスペクターで Mac を確認し、まずリスト セルの小さなアイコンの置き換えを開始します。
3. iPad のナビゲーション アクションを Mac ウィンドウのアクションに変更します。
- 対処方法: 新規、保存、キャンセルなどのウィンドウ レベルのアクションを iPad のナビゲーション バーから Mac 上のより適切な場所に移動します。
- 実行する価値がある理由: セッションの [新しいレシピ] ウィンドウでナビゲーション バーを非表示にし、[保存] と [キャンセル] を一番下に置きます。これらの操作は現在のウィンドウのフォーム データに直接影響するためです。
- 開始方法: Mac のイディオムの下にあるナビゲーション バーを非表示にします。 Interface Builder の Mac 特性バリエーションを使用して、専用のボタン領域をインストールします。
4. 静的な説明ビューを SwiftUI に置き換える
- 対処方法: プレーン テキストの説明ページを、GroupBox のグループ化、Toggle チェック ステップ、ピッカーの切り替えユニットなどの SwiftUI インタラクティブ ビューに変更します。
- 実行する価値がある理由: セッションでは、UIHostingController を通じて SwiftUI ビューを UIKit アプリに組み込む方法を示し、GroupBox、Toggle、および Picker が自動的に Mac の外観を取得します。
- 開始方法: まず部分的な
ContentViewを作成し、セッション内で GroupBox、Toggle、および Picker モードを再利用し、それを既存の UIKit ページに埋め込みます。
関連セッション
- Mac Catalyst の新機能 — 2020 年の Mac Catalyst の全体的なアップデートを補足し、Mac モードに最適化された上部の背景について言及します。
- Mac Catalyst のアクセシビリティ設計 - Mac Catalyst アプリのキーボード、マウス、およびアクセシビリティ対応のナビゲーション エクスペリエンスに関する作業を継続しています。
- トラックパッドとマウス入力の処理 — 間接入力、ポインターの移動、スクロール入力、およびジェスチャ認識機能の処理について説明します。
- macOS の新しい外観を採用する — AppKit と macOS Big Sur の設計の観点から Mac のコントロール、ツールバー、視覚的な階層を理解します。
コメント
GitHub Issues · utterances