Need
分割ビューを使ったアプリの基本構造
Default options
NavigationSplitView、.sidebar リスト、inspector(isPresented:)
Why it's needed
タッチ操作を前提に画面を順に開く方式よりも、常設のサイドバーに詳細ペインとインスペクタを組み合わせる方が、一般的な Mac アプリのレイアウトに合います。
.md to the page URL.
Codex use case
Codex を使って、サイドバー、詳細ペイン、インスペクタ、コマンド、設定を備えた Mac ネイティブの SwiftUI アプリの土台を作ります。
Codex と Build macOS Apps プラグインを使って、アプリのアイデアを NavigationSplitView ベースの Mac ネイティブアプリとして形にします。サイドバーの選択状態を保ちながら、メニュー、ツールバー、キーボードショートカットを追加し、環境設定を専用の Settings シーンに移します。
Codex を使って、サイドバー、詳細ペイン、インスペクタ、コマンド、設定を備えた Mac ネイティブの SwiftUI アプリの土台を作ります。
Codex と Build macOS Apps プラグインを使って、アプリのアイデアを NavigationSplitView ベースの Mac ネイティブアプリとして形にします。サイドバーの選択状態を保ちながら、メニュー、ツールバー、キーボードショートカットを追加し、環境設定を専用の Settings シーンに移します。
Codex と Build macOS Apps プラグインを使って、アプリのアイデアを NavigationSplitView ベースの Mac ネイティブアプリとして形にします。サイドバーの選択状態を保ちながら、メニュー、ツールバー、キーボードショートカットを追加し、環境設定を専用の Settings シーンに移します。
Related links
| Skill | Why use it |
|---|---|
| Build macOS Apps | macOS 向け SwiftUI の設計パターン、ウインドウ管理、AppKit 連携、ビルドと実行のスキルを使います。まずサイドバー、詳細ペイン、インスペクタを配置してアプリの骨組みを作り、メニューや設定を組み込みながら段階的に動作を確認します。 |
このユースケースでは、アプリのアイデアを形にする際に、タッチ操作を前提とした画面構成をそのまま広げるのではなく、デスクトップで自然に使える Mac アプリの骨組みを作ります。まず Codex にシーンモデルを選ぶよう依頼します。次に、選択状態を維持するサイドバー、選択項目を表示する詳細ペイン、補助的な操作やメタデータの表示に使うインスペクタを軸に、メインウインドウを設計してもらいます。

Codex にこのデスクトップ向けの構成を採用させ、シェルを中心にビルドと実行を繰り返すには、Build macOS Apps プラグインを使います。このプラグインに含まれる macOS 向けの SwiftUI パターンを扱うスキルは、シーンの設計や、サイドバー、インスペクタ、コマンド、設定の実装に適しています。Mac 固有の動作を一部だけ SwiftUI で実現できない場合に、小規模な AppKit ブリッジを追加する際にも役立ちます。
ナビゲーションを常に表示し、選択した項目を維持したい機能には、NavigationSplitView を優先して使います。サイドバーの行は標準の部品でシンプルに構成し、背景にはシステム標準のものを使います。独自のカードや情報量の多いメタデータは、詳細ペインまたはインスペクタに配置します。
import SwiftUI
struct Item: Identifiable, Hashable {
let id: String
let title: String
let systemImage: String
}
let items = [Item(id: "notes", title: "Notes", systemImage: "note.text"), Item(id: "photos", title: "Photos", systemImage: "photo")]
struct ItemDetailView: View {
let selection: String?
var body: some View { Text(selection ?? "Select an item").frame(maxWidth: .infinity, maxHeight: .infinity) }
}
struct ItemInspectorView: View {
let selection: String?
var body: some View { Text("Metadata: \(selection ?? "No selection")").padding().frame(minWidth: 220) }
}
@MainActor final class LibraryStore: ObservableObject {
@Published var entries = items
@Published var selection: String?
@Published var showInspector = true
func addItem() {
let item = Item(id: UUID().uuidString, title: "New Item", systemImage: "doc")
entries.append(item)
selection = item.id
}
}
struct LibraryRootView: View {
@StateObject private var store = LibraryStore()
@SceneStorage("LibraryRootView.selection") private var savedSelection: Item.ID?
@SceneStorage("LibraryRootView.showInspector") private var savedShowInspector = true
var body: some View {
NavigationSplitView {
List(selection: $store.selection) {
ForEach(store.entries) { item in
Label(item.title, systemImage: item.systemImage)
.tag(item.id)
}
}
.listStyle(.sidebar)
.navigationTitle("Library")
} detail: {
ItemDetailView(selection: store.selection)
.inspector(isPresented: $store.showInspector) {
ItemInspectorView(selection: store.selection)
}
}
.focusedSceneObject(store)
.onAppear {
store.selection = savedSelection
store.showInspector = savedShowInspector
}
.onChange(of: store.selection) { _, selection in
savedSelection = selection
}
.onChange(of: store.showInspector) { _, showInspector in
savedShowInspector = showInspector
}
}
}分割ペインのサイズを特殊な方法で調整する必要がある場合や、ウインドウ間の連携を低レベルで制御したい場合、レスポンダチェーンの動作をカスタマイズしたい場合は、SwiftUI で作った骨組みを維持し、その機能に必要な最小限の AppKit ブリッジだけを追加するよう Codex に依頼します。
Mac では、ユーザーがメニューバーやツールバーで主要な操作を見つけ、対応するキーボードショートカットも確認できるようにします。シーン単位の commands、状況に応じて使えるメニュー項目、ツールバーボタンを、アプリ内の同じ操作に結び付けるよう Codex に依頼します。これで、デスクトップのユーザーがジェスチャーでしか使えない操作を探し回らずに済みます。
@main
struct LibraryApp: App {
@FocusedObject private var store: LibraryStore?
var body: some Scene {
WindowGroup {
LibraryRootView()
}
.commands {
CommandMenu("Library") {
Button("New Item") {
store?.addItem()
}
.keyboardShortcut("n")
.disabled(store == nil)
Button("Toggle Inspector") {
store?.showInspector.toggle()
}
.keyboardShortcut("i", modifiers: [.command, .option])
.disabled(store == nil)
}
}
Settings {
LibrarySettingsView()
}
}
}詳細ペインに表示中の項目をコマンドの対象にするには、FocusedValue、シーンの状態、または明示的に管理する選択状態を使います。同じショートカットを複数箇所で登録することになりそうなら、管理箇所をまとめてコマンドの処理経路を一本化するよう Codex に依頼します。
Settings での設定管理アプリの設定には専用の Settings シーンを使い、次回以降も保持するユーザー設定は @AppStorage に保存します。通常、メインウインドウ内で設定画面に遷移するよりも、専用の設定シーンを使う方が Mac の操作感に合います。
struct LibrarySettingsView: View {
@AppStorage("showItemMetadata") private var showItemMetadata = true
var body: some View {
TabView {
Form {
Toggle("Show Item Metadata", isOn: $showItemMetadata)
}
.tabItem { Label("General", systemImage: "gearshape") }
}
.frame(width: 460, height: 260)
.scenePadding()
}
}このユースケースでは、アプリの構想、扱う主なデータや項目、ユーザーが行う主な操作をプロンプトに明記します。その操作の流れに沿って、まずデスクトップアプリの骨組みを作るよう Codex に依頼します。エージェントにビルドと実行で簡単な動作確認を行ってもらい、シーンの構成、コマンドと処理の対応、どこで状態を管理しているか、AppKit ブリッジが必要になった箇所をまとめてもらいます。
サイドバーの各行にはアイコンを 1 つ、タイトルを 1 行だけ表示し、補足が必要な場合も短い 1 行に収めます。情報量の多いカードや件数表示、メタデータは詳細ペインまたはインスペクタに移し、一覧から目的の項目を見つけやすくします。
アプリ全体に適用するユーザー設定は、メイン画面から遷移する設定画面を追加する代わりに、Settings に設定項目を配置し、@AppStorage で値を保存するよう Codex に依頼します。設定はアプリメニューから開けるようにします。
ファイルを開くパネルや保存するパネル、ファーストレスポンダの制御、独自の NSView が必要な場合は、ウインドウ全体を AppKit で書き直すのではなく、状態モデルは SwiftUI で管理し、その機能に限って AppKit を使います。
Need
Default options
Why it's needed
Need
分割ビューを使ったアプリの基本構造
Default options
NavigationSplitView、.sidebar リスト、inspector(isPresented:)
Why it's needed
タッチ操作を前提に画面を順に開く方式よりも、常設のサイドバーに詳細ペインとインスペクタを組み合わせる方が、一般的な Mac アプリのレイアウトに合います。
Need
デスクトップ向けの操作と設定
Default options
commands、CommandMenu、キーボードショートカット、Settings シーン
Why it's needed
メニューバーからの操作、ショートカット、専用の設定ウインドウを用意すると、iOS の画面をデスクトップサイズに広げただけでは得られない、Mac アプリらしい操作感が生まれます。
Need
状態の管理主体
Default options
@State、@SceneStorage、@AppStorage、選択状態の明示的なバインディング
Why it's needed
Codex は、安易にビューモデルを追加せずに、サイドバーの選択状態、インスペクタの表示状態、ユーザーの環境設定を一貫して管理できます。
Need
SwiftUI で対応しきれない動作の実装
Default options
用途を絞った NSViewRepresentable または NSWindow ブリッジを介した AppKit との連携
Why it's needed
AppKit は、SwiftUI で無理なく実装できないプラットフォーム固有の動作に限って使います。シーンの状態と選択状態は SwiftUI 側で一元管理します。
| Need | Default options | Why it's needed |
|---|---|---|
| 分割ビューを使ったアプリの基本構造 | NavigationSplitView 、 .sidebar リスト、 inspector(isPresented:) | タッチ操作を前提に画面を順に開く方式よりも、常設のサイドバーに詳細ペインとインスペクタを組み合わせる方が、一般的な Mac アプリのレイアウトに合います。 |
| デスクトップ向けの操作と設定 | commands 、 CommandMenu 、キーボードショートカット、 Settings シーン | メニューバーからの操作、ショートカット、専用の設定ウインドウを用意すると、iOS の画面をデスクトップサイズに広げただけでは得られない、Mac アプリらしい操作感が生まれます。 |
| 状態の管理主体 | @State 、 @SceneStorage 、 @AppStorage 、選択状態の明示的なバインディング | Codex は、安易にビューモデルを追加せずに、サイドバーの選択状態、インスペクタの表示状態、ユーザーの環境設定を一貫して管理できます。 |
| SwiftUI で対応しきれない動作の実装 | 用途を絞った NSViewRepresentable または NSWindow ブリッジを介した AppKit との連携 | AppKit は、SwiftUI で無理なく実装できないプラットフォーム固有の動作に限って使います。シーンの状態と選択状態は SwiftUI 側で一元管理します。 |