iphone-duo-hinge-and-scenes について
iPhone Duo開発者向けに、ヒンジの変化、Split Viewでのマルチタスク、両ディスプレイへのUI表示を扱うスキルです。複数ウィンドウやシーンアクセサリの可用性と処理方法も説明します。
主な機能
- 01ヒンジの状態と連続角度を取得
- 02Split Viewの左右に応じてレイアウトを調整
- 03新しいシーンの要求失敗に対応
- 04シーンアクセサリの可用性を監視
- 05外側ディスプレイにカメラアクセサリを表示
活用シーン
- 01ヒンジ角度に連動した操作エフェクト
- 02Split Viewの左右でレイアウトを検証
- 03新しいウィンドウを作成できない場合に対応
- 04外側ディスプレイで被写体にカメラ映像を表示
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mirzaaghazadeh/ iphone-duo-skills --skill iphone-duo-hinge-and-scenesインストール後、Claude Code で/iphone-duo-hinge-and-scenesを入力して読み込まれたか確認します。
詳細
ヒンジ、マルチタスキング、シーン
iPhone Duo 独自の3つの機能を、野心的な順に紹介します。 ヒンジへの反応、Split View への参加、そして両方のディスプレイに同時に独自の UI を表示することです。
ヒンジ
システム自体がヒンジに反応します。デバイスを開くと、壁紙がズーム効果で角度に反応します。アプリも同じ信号を読み取れます。
SwiftUI では onHingeChange 修飾子を、UIKit では UIHingeInteraction を使用します。
どちらからも次の情報を取得できます。
- 大まかな ステータス — 閉じている、一部開いている、完全に開いている
- 連続的な角度。リアルタイムで更新されます
onHingeChange は、クロージャに前回と現在のヒンジコンテキストを渡します。
UIHingeInteraction は代わりに、ハンドラーにインタラクションと Update を渡し、ビューが階層間を移動したときにも発火します。
型の違いに注意してください。フレームワークごとに異なります。
- SwiftUI の角度は
Angleです。UIKit の角度はラジアン単位のCGFloatです。 - SwiftUI の
DeviceHinge.Statusは構造体なので、switchにはdefaultが必要です。 UIKit のUIHinge.Statusは列挙型で、4つ目のケースとして.unknownがあります。 - ステータスは角度 と デバイスの向きからシステムが判断するため、しきい値から再計算しないでください。更新頻度と精度はシステムのポリシーで決まるため、特定の頻度を前提にしないでください。
完全なシグネチャ、再利用可能な正規化関数、エフェクトのパターンについては、
../iphone-duo-dual-pane-patterns/SKILL.md を参照してください。
値を使用する前に、次の2点を確認してください。
- そもそもヒンジがあるか?
nilのヒンジは、アプリがヒンジのないデバイスで実行されていることを意味します。同じバイナリでも、多くのデバイスで動作します。 - デバイスは必要な状態か? 通常、更新が必要なのは一部開いているときだけです。また、角度を使っていたエフェクトが古い値のまま残らないよう、ユーザーがデバイスを完全に開いたときに値をリセットする
else分岐も必要です。
その後、角度をパラメーターに対応付けて、状態を更新します。
ヒンジの用途
インタラクションとエフェクト。 角度はリアルタイムの連続的な入力ストリームです。センサーのように動作し、連続的に変化に応じるものに適しています。ワーミーバーのように、折りたたみ角度でピッチベンドを動かすのが適切なアイデアです。
レイアウトには使わないでください。 ヒンジ角度を使ってビューをレイアウトしないでください。レイアウトには、ヒンジのないデバイスでも宣言的かつテスト可能で、正しく動作する適切なツールがあります。配置と予約領域については、
../iphone-duo-adaptive-layout/SKILL.md を参照してください。ここで角度を使うと、折りたたみ中にレイアウトが頻繁に変わり、それ以外のあらゆる場面でも動作しなくなります。
Split View のマルチタスキング
すべてのアプリが参加します。 おなじみのホームジェスチャで2つのアプリを並べて表示します。アプリを片側にドラッグしてドロップします。もう1つのレイアウトでは、ピクチャ・イン・ピクチャが固定されているときに、ビデオとアプリを重ねて表示します。アプリはどちらの場合も同じように動作します。
アプリがすでに iPad や iPhone ミラーリングでのサイズ変更に対応していれば、ほとんど準備はできています。システムはレイアウトの判断に使えるサイズクラスとシーンのジオメトリを提供します。
../iphone-duo-readiness/SKILL.md の一般的なガイダンスはそのまま適用できます。
テストすべき重要な点があります。Split View では、縦方向に配置されたバーのコンテンツが、アプリのどちら側に表示されるかによって、左右どちらにも現れることがあります。Device Hub でアプリを両側にドラッグし、左右非対称のセーフエリア処理が正しく機能することを確認してください。
複数のシーン
iPhone Duo は、アプリの UI を複数同時に実行できる初めての iPhone です。アプリがすでに iPad でこの機能に対応していれば、ここでも動作します。
ただし、1つだけまったく新しい動作があります。
外側のディスプレイでは新しいウインドウを作成できません。 新しいウインドウの作成は内側のディスプレイに限定されており、利用可能かどうかはユーザーがデバイスを開閉するたびに変わります。iPad にはこの動的な利用可否はありません。
その結果、次のことが必要です。
- 新しいシーンのリクエスト時にエラーを処理してください。 iPad では常に成功していたリクエストが、失敗することがあります。
UIWindowSceneActivationを優先してください。新しいウインドウが利用できないときに自動で非表示になるため、ユーザーが実行できない操作要素をタップすることはありません。
シーンアクセサリ
シーンアクセサリを使うと、アプリのメイン UI と連動するコンテンツを別のディスプレイに表示できます。Duo 専用の機能ではありません。同じ仕組みは、外部ディスプレイでプレイするゲームのコントローラーとして iPhone を使う場合にも利用されます。ただし、iPhone Duo では、すべてのユーザーが使えるディスプレイが 2 つあります。
システムは利用可能かどうかを動的に制御します。アクセサリはデフォルトで有効になっており、いつでも切り替えられるため、利用可能かどうかを決めつけず、状態を監視してください。状態の監視を使うか、onAvailabilityChange モディファイアを使い、現在の状態を UI に反映してください(たとえば、アクセサリを表示できない場合は切り替えボタンを無効にします)。
CameraCaptureAccessory
カメラアプリでは、CameraCaptureAccessory を使うと、アプリのメイン UI を内側のディスプレイに表示したまま、UI を外側のディスプレイに表示できます。撮影時に被写体が何かを見られるため、子どもを楽しませるものを見せたり、カメラの前にいる被写体にテレプロンプターを表示したりできます。
利用可能になるには、2 つの条件があります。アプリが内側のディスプレイでフルスクリーン表示されていることと、カメラセッションがアクティブであることです。
カメラ UI と同じビューにアクセサリを登録してください。 このようにスコープを設定すると、追加のライフサイクルコードを記述しなくても、カメラビューに合わせてアクセサリが表示・非表示になります。SwiftUI では、カメラビューに sceneAccessory モディファイアを適用します。
アクセサリを切り替えるツールバーコントロールを追加するのも自然な組み合わせです。モデルから状態を制御し、onAvailabilityChange を使って、デバイスが閉じているときなど、アクセサリを利用できない場合にコントロールを無効にします。
どの物理カメラがストリーミングしているか、また 2 つのディスプレイが関わる場合にカメラが実際にどちらを向いているかといった、カメラ固有の詳細については、../iphone-duo-camera/SKILL.md を参照してください。この問題は非常に微妙なため、方向コーディネーターがその判断を担います。
チェックリスト
- まずサイズ変更に対応します。それができれば、Split View も正しく動作します。
- あらゆる向きで、Split View の両側にアプリを表示してテストします。
- アプリが複数ウィンドウに対応している場合は、シーン要求の失敗を処理し、
UIWindowSceneActivationを採用します。 - ヒンジに連動するエフェクトがアプリを本当に改善するか検討し、そのうえでヒンジが
nilの場合に備え、対象とする範囲からデバイスが外れたときに状態をリセットします。 - カメラアプリでは、レンズの前にいる人にとって、外側のディスプレイに
CameraCaptureAccessoryを表示すると便利かどうかを検討します。