关于 iphone-duo-hinge-and-scenes
面向 iPhone Duo 开发者的技能,讲解如何响应铰链状态、参与分屏多任务,以及在两个显示屏上呈现应用界面。还说明多窗口与场景附件的可用性和处理方式。
主要功能
- 01读取铰链状态与连续角度
- 02适配分屏两侧的布局
- 03处理多窗口场景请求失败
- 04观察场景附件的可用状态
- 05在外屏显示相机辅助界面
适用场景
- 01根据铰链角度驱动交互效果
- 02验证应用在分屏两侧的布局
- 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 独有的三项能力,按实现难度递增排列: 响应铰链、参与 Split View,以及同时在两块显示屏上显示自己的 UI。
铰链
系统本身会响应铰链——设备打开时,墙纸会随角度变化产生缩放效果。App 也可以读取同一信号。
在 SwiftUI 中使用 onHingeChange 修饰符,或在 UIKit 中使用
UIHingeInteraction。两者都会提供:
- 粗略的状态——闭合、部分打开、完全打开
- 连续角度,实时更新
onHingeChange 会将上一个和当前的铰链上下文传给闭包。
UIHingeInteraction 则会将交互和一个 Update 传给处理器,
并且在视图移至不同层级时也会触发。
注意这些类型的差异——不同框架中的类型并不相同:
- SwiftUI 的角度类型是
Angle;UIKit 的角度类型是以弧度表示的CGFloat。 - SwiftUI 的
DeviceHinge.Status是结构体(switch需要default); UIKit 的UIHinge.Status是枚举,另有第四种情况.unknown。 - 系统会根据角度和设备方向来判定状态,因此不要自行根据阈值重新计算。 更新频率和精度由系统策略决定——不要假设固定频率。
完整签名、可复用的归一化器和效果模式见
../iphone-duo-dual-pane-patterns/SKILL.md。
使用该值前,请先检查两件事:
- 设备是否有铰链? 铰链值为
nil意味着 App 正在没有铰链的设备上运行。同一个二进制文件,大多数设备都能运行。 - 设备是否处于你关心的状态? 通常你只需要在设备部分打开时接收更新——并且需要一个
else分支来重置由角度驱动的值,以免用户将设备完全打开后,效果仍停留在过时的值上。
然后将角度映射到你的参数并更新状态。
铰链的用途
交互和效果。 角度是实时、连续的输入流——它的表现类似传感器,适合用于需要连续响应的事物。根据折叠角度驱动音高弯音,就像使用颤音摇杆一样,是合适的应用方式。
不是布局。 不要根据铰链角度来布局视图。布局有更合适的工具,它们具有声明性、可测试,并且在没有铰链的设备上也能正确工作:排列方式和预留区域,见
../iphone-duo-adaptive-layout/SKILL.md。在这里使用角度会导致布局在折叠过程中不断抖动,并在其他所有情况下失效。
Split View 多任务处理
每个 App 都能参与。 两个 App 并排显示,通过熟悉的主屏幕手势创建——将一个 App 拖到一侧并放下。此外还有第二种布局:当画中画窗口固定时,可将视频和 App 堆叠显示。你的 App 对这两种布局的处理方式相同。
如果 App 已支持在 iPad 或 iPhone 镜像模式下调整大小,那么大部分工作就已完成。系统会提供尺寸类别和场景几何信息,供你据此决定布局;../iphone-duo-readiness/SKILL.md 中的一般指导同样适用。
值得测试的一点:在 Split View 中,垂直排列的栏内容可能出现在 App 的任意一侧,具体取决于 App 所处的半边。在 Device Hub 中将 App 分别拖到两侧,并检查非对称安全区域处理是否正常。
多个场景
iPhone Duo 是首款支持同时运行同一 App 的多个 UI 实例的 iPhone。如果 App 已在 iPad 上支持此功能,在这里也能正常工作。
不过,有一种行为确实是全新的:
无法在外侧显示屏上创建新窗口。 新窗口只能在内侧显示屏上创建,并且是否可用会随用户打开和合上设备而变化。iPad 上没有这种动态可用性。
因此:
- 请求新场景时要处理错误。 在 iPad 上总能成功的请求,现在可能会失败。
- 优先使用
UIWindowSceneActivation,当新窗口不可用时,它会自动隐藏——这样用户就不会点击无法生效的操作入口。
场景配件
场景配件可在另一块显示屏上,将额外内容与应用的主界面搭配显示。它们并非 Duo 专属——同一机制也用于将 iPhone 用作外接显示屏上游戏的控制器——但 iPhone Duo 为每位用户提供了两块显示屏。
系统会动态控制配件的可用性。配件默认启用,且可随时切换,因此应观察其可用性,而不要想当然地认为它始终可用:使用可用性观察跟踪或 onAvailabilityChange 修饰符,并在界面中反映当前状态(例如,在无法显示配件时禁用切换按钮)。
CameraCaptureAccessory
对于相机应用,CameraCaptureAccessory 会将界面放在外侧显示屏上,同时让应用的主界面留在内侧显示屏上。这样,被拍摄者在你拍摄时也能看到一些内容——比如给孩子播放有趣的东西,或为镜头前的拍摄对象运行提词器。
可用性受两个条件限制:应用必须在内侧显示屏上全屏显示,并且必须有活动的相机 Session。
在与相机界面相同的视图上注册配件。 这样限定作用范围后,配件会随相机视图本身一起出现和消失,无需额外的生命周期代码。在 SwiftUI 中,可将 sceneAccessory 修饰符应用于相机视图。
添加一个用于切换配件的工具栏控件是很自然的搭配——由模型驱动该控件,并使用 onAvailabilityChange 在配件不可用时禁用控件,例如设备合上时。
相机相关细节——正在传输画面的物理相机,以及启用两块显示屏后相机实际朝向的方向——请参阅 ../iphone-duo-camera/SKILL.md。这个问题确实相当微妙,而方向协调器正是为了解决它而存在的。
检查清单
- 优先支持调整大小。做到这一点后,分屏视图也就能正确运行。
- 在分屏视图的两侧分别测试应用,并覆盖每种设备姿态。
- 如果应用支持多个窗口,请处理场景请求失败的情况,并采用
UIWindowSceneActivation。 - 考虑由铰链驱动的效果是否确实能改善应用体验,然后针对铰链为
nil的情况进行处理,并在设备离开关注范围时重置状态。 - 对于相机应用,评估在外侧显示屏上使用
CameraCaptureAccessory是否能为镜头前的人带来帮助。