swift-focusengine-pro について
swift-focusengine-pro は、Apple プラットフォームのフォーカス管理コードをレビューするスキルです。各プラットフォームの規則、アクセシビリティ、フォーカス復元、レイアウトを確認し、問題と修正コードを示します。
主な機能
- 01プラットフォーム別のフォーカス規則確認
- 02フォーカスのアンチパターン検出
- 03フォーカス表示と復元のレビュー
- 04アクセシビリティと非同期処理の確認
- 05ファイル別の指摘と修正コード
活用シーン
- 01SwiftUI または UIKit のフォーカスナビゲーションのレビュー
- 02Apple 各プラットフォーム対応アプリの問題調査
- 03キーボード、リモコン、Digital Crown、視線操作の確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mhaviv/ swift-focusengine-agent-skill --skill swift-focusengine-proインストール後、Claude Code で/swift-focusengine-proを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
CONTRIBUTING.mdLICENSECODE_OF_CONDUCT.md.gitignoreCHANGELOG.mdREADME.mdllms.txtpackage.json.claude-plugin/plugin.jsonmarketplace.json.github/pull_request_template.md.github/ISSUE_TEMPLATE/bug_report.mdfeature_request.mdagents/openai.yamlreferences/debugging.mdaccessibility-focus.mdasync-focus.mdanti-patterns.mdfocus-restoration.mdfocus-styling.mdios-focus.mdwatchos-focus.mduikit-focus.mdswiftui-focus.mdvisionos-focus.mdmacos-focus.mdlayout-patterns.mdrealitykit-focus.md詳細
フォーカス管理コードをレビューし、正確性、最新の API の使用状況、Apple のフォーカスエンジンのルールへの準拠を確認します。すべての Apple プラットフォームが対象です。実際に問題がある場合のみ報告し、些細な点を指摘したり、問題を捏造したりしないでください。
レビュー手順:
references/anti-patterns.mdを参照して、重大なアンチパターンを確認します。- 対象プラットフォームを特定し、適切なリファレンスを読み込みます。
- tvOS:
references/swiftui-focus.mdとreferences/uikit-focus.md。 - iOS/iPadOS:
references/ios-focus.md(フォーカスグループ、ハロー、キーボードナビゲーション)。 - watchOS:
references/watchos-focus.md(Digital Crown、順次フォーカス)。 - visionOS:
references/visionos-focus.md(視線、ホバーエフェクト)とreferences/realitykit-focus.md(RealityKit のエンティティ、ジェスチャ、ボリューム)。 - macOS:
references/macos-focus.md(キー表示ループ、フォーカスリング、NSView のフォーカス、メニュー用の focusedValue、Mac Catalyst)。 - クロスプラットフォームの場合:関連するすべてのリファレンスを読み込みます。
- tvOS:
references/focus-styling.mdを参照して、フォーカスのスタイルと視覚的なフィードバックを確認します。references/focus-restoration.mdを参照して、フォーカスの復元とデータ再読み込みへの対応を確認します。references/layout-patterns.mdを参照して、フォーカスセクションを分離するレイアウトパターンを監査します。references/async-focus.mdを参照して、async/await とデータ読み込み時のフォーカスパターンを確認します。references/accessibility-focus.mdを参照して、アクセシビリティとの統合を確認します。references/debugging.mdを参照して、デバッグとテストの実践方法を確認します。
部分的なレビューを行う場合は、関連するリファレンスファイルのみを読み込みます。
基本的な指示
tvOS
- tvOS はフォーカスベースのナビゲーションモデルを使用します。すべてのインタラクティブ要素に、Siri Remote の方向パッドから移動できる必要があります。
- フォーカスの移動は完全に幾何学的に行われます。フォーカスエンジンは、現在フォーカスされているビューからスワイプした方向に矩形を描き、その矩形内で最も近いフォーカス可能なビューを選びます。
- 幾何学的な経路上に何もなければ、フォーカスは移動しません。例外はありません。隙間をつなぐには、
.focusSection()(SwiftUI)またはUIFocusGuide(UIKit)を使用します。 - tvOS でインタラクティブ機能の切り替えに
.disabled()を使用しないでください。ビューがフォーカスチェーンから完全に取り除かれます。tvOS では.allowsHitTesting(false)も信頼できません(isUserInteractionEnabled = falseにマッピングされる場合があります)。推奨される方法は、ボタンのクロージャ内でアクションを制御するか、リストに対して@FocusStateと.disabled()を組み合わせたゲーティングパターンを使用することです(アンチパターン #25)。 prefersDefaultFocus(_:in:)は tvOS のScrollView内では機能しません。代わりにdefaultFocus(_:_:priority:)を使用します。注:.userInitiatedを指定したdefaultFocusが実行されるのは初回表示時のみで、再入場時には実行されません。ScrollViewReader.scrollTo()よりScrollPositionを優先してください。命令的なscrollToは、フォーカスエンジンとのフィードバックループを引き起こします(アンチパターン #26)。- 必ず実機の Apple TV でテストしてください。シミュレータではフォーカスの動作が異なります。
iOS/iPadOS
- フォーカスは副次的な操作モデルで、ハードウェアキーボードが接続されている場合にのみ有効になります。
- Tab キーでフォーカスグループ間を移動し、矢印キーでグループ内を移動します。この 2 段階のモデルは tvOS にはありません。
- カスタムフォーカスグループを定義するには
focusGroupIdentifier(iOS 14 以降、UIKit)を使用します。この API は tvOS では利用できません。 - システムのフォーカスリングをカスタマイズするには
UIFocusHaloEffectを使用します。これは tvOS では利用できません。 - キーボードナビゲーションを有効にするには、コレクションビューやテーブルビューで
allowsFocus = trueとselectionFollowsFocus = trueを設定します。 - キーボードフォーカスがなくてもアプリが完璧に動作する必要があります。必ずタッチ操作のみでもテストしてください。
watchOS
- フォーカスは、Digital Crown の入力を適切なビューにルーティングします。フォーカスは緑色の枠線で示されます。
- フォーカスは順次(レイアウト順)に移動し、空間的/方向的には移動しません。
.focusSection()は watchOS では利用できません。.focusable()は必ず.digitalCrownRotation()より前に指定してください。順序を逆にすると、Crown の入力が通知なしに機能しなくなります。- システムコントロール(Picker、Stepper、Toggle)には
.focusable()を追加しないでください。これらのコントロールはすでにフォーカスに対応しています。
visionOS
- 視線 = ホバーによるターゲティングであり、フォーカスではありません。
onHover(perform:)は視線では呼び出されず、ポインターデバイスでのみ呼び出されます。 - 視線に対する視覚的なフィードバックには
.hoverEffect()を使用します。システムコントロールには自動的に適用されますが、カスタムビューでは明示的に指定する必要があります。 @FocusStateはキーボード(Magic Keyboard)、VoiceOver、またはスイッチコントロールでのみ有効になります。- RealityKit のエンティティで視線操作を行うには、
InputTargetComponent、CollisionComponent、HoverEffectComponentが必要です。 .focusEffectDisabled()はキーボードフォーカスリングを非表示にし、.hoverEffectDisabled()は視線によるホバーを無効にします。この2つは異なります。
macOS
- macOS ではキービューのループが使用されます。Tab/Shift-Tab で、定義された順序に従ってビュー間を移動します。これは tvOS のような空間的な移動ではありません。
- カスタムの NSView サブクラスでは、
acceptsFirstResponderをオーバーライドしてtrueを返す必要があります。デフォルト値はfalseであるため、ビューは Tab ナビゲーションから認識されません。 - NSWindow の
autorecalculatesKeyViewLoop = trueは、手動で設定したすべてのnextKeyView接続を上書きします。どちらか一方の方法を選んでください。 - フォーカスリングをカスタマイズするには、NSView の
focusRingType、focusRingMaskBounds、drawFocusRingMask()をオーバーライドします。 - macOS では、メニューバーのコマンドを現在の選択項目に応じて動作させるために、
focusedValue/focusedSceneValueが重要です。 - Mac Catalyst は iPad の
UIFocusSystemを継承します。iPad アプリがキーボードフォーカスに対応していない場合、Catalyst アプリも対応しません。 - フルキーボードアクセスはデフォルトでオフです。ほとんどのユーザーは、すべてのコントロールではなく、テキストフィールドとリストの間だけを Tab で移動します。
すべてのプラットフォーム
- Button や NavigationLink に
.focusable()を追加しないでください。これらはすでにフォーカス可能です。追加すると、フォーカス用のラッパーが二重に作られます。 - 同じビュー階層の分岐で、
@FocusState(SwiftUI)と UIKit のフォーカス API(setNeedsFocusUpdate)を混在させないでください。 - VoiceOver のフォーカス(
@AccessibilityFocusState)は、UI のフォーカス(@FocusState)とは完全に別のものです。
ツールチェーンの状況(Xcode 27 ベータ版、2026 年 8 月時点)
- OS 26 で追加されたフォーカス API は、
accessibilityDefaultFocus(_:_:)(SwiftUI、すべてのプラットフォームで 26.0 以降に対応。VoiceOver のデフォルトフォーカスを設定します。references/accessibility-focus.mdを参照)ただ1つであり、フォーカス関連の非推奨 API はありません。OS 27 ベータ版でも追加はありません。リリースノートだけでなく、インストール済みの5つのプラットフォームすべての 26.5 SDK インターフェースをスキャンして確認済みです。フォーカス周辺で変更されたその他の点として、Liquid Glass は tvOS 26 でフォーカス中のコントロールの外観を変更します(対象は 4K 第2世代以降のみで、それ以前のデバイスでは従来のガラス適用前の表示が維持されます)。ControlSizeは tvOS 26 以降で動作し、.sidebarAdaptableTabView(tvOS 18 以降)ではタブ領域が先頭側のサイドバーに移動し、visionOS 26 では視線によるスクロールをオプトインで有効にできます(.scrollInputBehavior(.enabled, for: .look))。 - 27 SDK では、iOS/iPadOS/tvOS/visionOS/Mac Catalyst でシーンベースのライフサイクルが必須です(これがないとアプリは起動せず、macOS と watchOS は影響を受けません)。また、tvOS 27 ではダイナミックタイプが追加されます。どちらもフォーカス API ではなく、フォーカスのサンプルコードの構成とサイズに影響します。
- Swift 6.2:新しい Xcode 26 プロジェクトでは、モジュール全体に MainActor 分離がデフォルトで適用されます。どちらの環境でもコンパイルできる必要がある例では、明示的な
@MainActorを維持してください(references/async-focus.mdを参照)。
出力形式
ファイルごとに指摘事項を整理してください。各問題について、次の内容を記載してください。
- ファイル名と該当する行番号。
- 違反しているルールの名前(例:「通常のコントロールを tvOS のフォーカスチェーンから除外しないでください。
.disabled()を使用するのではなく、アクションをゲートしてください。意図的な二重@FocusStateによるエントリー制御パターン(アンチパターン #25)が唯一の例外です」)。 - 簡潔な修正前/修正後のコード。
問題のないファイルは省略してください。最後に、最初に対応すべき、影響の大きい変更を優先順位順にまとめてください。
出力例:
TopicsView.swift
49 行目:.disabled() によってビューが tvOS のフォーカスチェーンから除外されます(アンチパターン #1)。
// Before
TopicClipsGridView(...)
.disabled(!wrapper.isGridFocusable)
// After — gate the action, not the view
TopicClipsGridView(...)
.opacity(wrapper.isGridFocusable ? 1.0 : 0.5)
// Move the guard inside the button/action closures instead
72 行目:垂直レイアウト内の水平 ScrollView に .focusSection() がありません。
// Before
ScrollView(.horizontal) {
HStack { /* row items */ }
}
// After
ScrollView(.horizontal) {
HStack { /* row items */ }
}
.focusSection()
まとめ
- フォーカスの破損(重大): 49 行目の
.disabled()によって、グリッド全体がフォーカスチェーンから除外されます。 - フォーカスの飛び(高):
.focusSection()がないため、行をまたいだフォーカスの飛びが発生します。
出力例終わり。
リファレンス
references/anti-patterns.md— フォーカス移動を妨げる重大なミス:tvOS/一般向けとmacOS固有のセクションにまたがる、番号付きのアンチパターン30項目。references/swiftui-focus.md— SwiftUIのフォーカスAPI:@FocusState、focusSection、prefersDefaultFocus、focused、defaultFocus、onMoveCommand。references/uikit-focus.md— UIKitのフォーカスAPI:UIFocusEnvironment、UIFocusGuide、shouldUpdateFocus、didUpdateFocus、preferredFocusEnvironments、UIFocusDebugger。references/focus-styling.md— フォーカスの視覚的なフィードバック:isFocusedを使ったButtonStyle、FocusBorder、ホバーエフェクト、拡大/影のアニメーション、macOSのフォーカスリングのスタイル設定。references/focus-restoration.md— データの再読み込み、画面遷移、非同期更新後のフォーカスの処理。references/layout-patterns.md— tvOSの一般的なレイアウト:コレクションのテーブル、サイドバー+コンテンツ、タブバー、横方向の棚。references/ios-focus.md— iOS/iPadOS固有:フォーカスグループ、focusGroupIdentifier、UIFocusHaloEffect、キーボードナビゲーション、allowsFocus、selectionFollowsFocus。references/watchos-focus.md— watchOS固有:Digital Crownのルーティング、順次フォーカス、digitalCrownRotation、フォーカス順序。references/visionos-focus.md— visionOS固有:視線、フォーカス、ホバーの違い、HoverEffect、HoverEffectGroup、RealityKitのHoverEffectComponent、空間入力。references/macos-focus.md— macOS固有:キー・ビュー・ループ、NSViewのフォーカス(acceptsFirstResponder、canBecomeKeyView)、フォーカスリングのカスタマイズ、メニュー向けのfocusedValue、Mac Catalyst、フルキーボードアクセス。references/realitykit-focus.md— RealityKitエンティティのホバー:HoverEffectComponent、コリジョンシェイプ、ジェスチャー、シェーダーエフェクト、SwiftUIとRealityKitを組み合わせた階層構造。references/async-focus.md— 非同期フォーカスのパターン:@MainActorによる調整、データ読み込み後のフォーカス、NavigationStackのポップ、Taskのキャンセル、デバウンス。references/accessibility-focus.md— アクセシビリティとの統合:@AccessibilityFocusState、VoiceOverとフォーカス、フルキーボードアクセス、スイッチコントロール、視差効果を減らす設定。references/debugging.md— UIFocusDebugger、_whyIsThisViewNotFocusable、起動引数、Quick Look、macOSのファーストレスポンダーのデバッグ。
コメント
Markdown 対応