
iPhone Duo 多屏开发:铰链数据与场景配件怎么用
这是「iPhone Duo 六支苹果官方 Tech Talks 视频」系列的第五篇,前四篇分别讲设计原则、适配准备、导航栏和自适应布局,最后一篇会聊相机。本文聚焦三个容易混在一起的问题:怎样读取铰链状态,怎样让应用适应分屏和多场景,以及怎样把一部分界面放到另一块屏幕上。
先分清三种能力
iPhone Duo 的两块屏幕并不只意味着把同一个界面拉宽。应用需要处理铰链从合上到打开的变化,也要接受两个应用并排运行的尺寸,还可以让主界面和附加界面分别出现在内屏、外屏。
这三件事使用的思路不同。铰链数据适合驱动交互和特效;布局问题交给尺寸类、场景几何,以及 arrangement 和 region API;跨屏内容则使用多场景和场景配件。先把边界分好,后面的实现会简单很多。

响应铰链:读取状态,也读取连续角度
SwiftUI 提供了 onHingeChange 修饰符,UIKit 提供 UIHingeInteraction。两者都能报告铰链的高级状态:closed、partially open 和 fully open,也就是关闭、部分打开和完全打开。除了这些离散状态,铰链角度还会持续更新。
这意味着应用可以在用户打开设备的过程中即时反馈。比如,壁纸可以随角度产生缩放,某个控件可以在部分打开时出现,特效也可以跟着角度变化。这里的重点是“实时观察”,不是拿铰链角度替代布局系统。

使用 onHingeChange 时,闭包会收到两个参数:之前的铰链上下文和当前的铰链上下文。如果只关心最新结果,就读取当前上下文。先检查它是否为空,因为应用也可能运行在没有铰链的设备上。没有铰链时,不要继续读取角度,更要把由铰链驱动的状态恢复到默认值。
一个稳妥的判断顺序是:先判断当前铰链上下文是否存在,再确认设备处于部分打开状态,最后根据角度更新交互状态。如果上下文为空,或者设备不在需要的状态,就执行重置逻辑。这样应用在普通 iPhone、设备合上和状态切换时都不会留下上一次的结果。
用铰链角度做交互:吉他音高弯曲
Tech Talks 里的例子是一款可以演奏的吉他应用。它把音高弯曲值存成状态,再从 Instruments 视图传给吉他视图;吉他视图通过 onHingeChange 读取铰链,模拟吉他摇把的 pitch bend。

实现上,不必为每一种铰链状态写一套界面。闭包只需要关注当前铰链上下文:当设备部分打开时,根据连续角度计算音高弯曲值并更新状态;其他情况则把音高弯曲值重置。重置很重要,否则用户合上设备后再次打开应用,音效可能还停留在上一次的弯曲值。
这个例子也说明了铰链 API 的合适用法:把角度当作输入信号,交给交互逻辑处理。可以用它驱动音高、动画或视觉反馈,但不要让它负责决定视图该放在哪一块屏幕。
铰链数据不是布局 API
铰链数据会随设备动作实时更新,适合交互和特效。布局则应使用 arrangement 和 region API。应用应该根据系统提供的布局信息安排内容,而不是自己读取角度、猜测两块屏幕的尺寸,再手动计算位置。
例如,一个编辑器是否要把工具区放到另一侧、一个计算器是否要在更宽的区域显示更多按键,这些都属于布局决策。角度只告诉你设备正在怎样变化,不能替代系统对可用区域的描述。两类逻辑分开后,布局代码也更容易在不同姿态和尺寸下复用。
分屏多任务:先把窄窗口做好
iPhone Duo 上的多任务处理支持两个应用并排布局,所有应用都需要参与。系统还提供了尺寸类和场景几何,帮助应用做布局决策。视频中提到,如果应用已经支持 iPad 上的尺寸调整,或支持 iPhone 镜像,那么适配工作已经有了不错的基础。

iPhone Duo 还有一种新的布局方式,会把视频和应用叠加在一起。对应用来说,这种布局与分屏布局的处理方式相同,仍然应该依据当前可用空间调整界面,而不是针对某个固定姿态写死尺寸。
落到实际界面上,优先检查窄宽度下的内容顺序、文字截断和控件间距。Podcast 播放器可能要收起次要信息,计算器要保证按键仍然可操作,编辑器则需要确认工具栏不会挡住主要内容。先把应用放进各种尺寸的窗口里观察,再决定哪些内容应该隐藏或重排。
多场景:内屏可以创建新窗口,外屏不行
iPhone Duo 是首款支持应用 UI 多实例的 iPhone。如果应用已经在 iPad 上支持多实例,那么在 iPhone Duo 上也支持。不过,这里有一个明确限制:iPad 可以随时创建新窗口,iPhone Duo 的外屏不能创建新窗口;创建新窗口的行为只适用于内屏。

因此,请把“请求新场景”当成可能失败的操作。使用 UIWindowSceneActivationAction 请求时,要处理无法创建新窗口的情况。系统会在不能创建新窗口时自动隐藏这个 action,应用仍应正确处理请求失败,避免界面留下一个看起来能用、实际没有结果的入口。
这项限制会影响窗口入口的设计。内屏上可以提供创建新窗口的操作,外屏则不要假定同样的入口始终有效。测试多场景时,至少要覆盖内屏创建、外屏尝试创建,以及设备姿态变化后的场景恢复。
场景配件:给另一块屏幕配一个附加界面
分屏多任务不是跨屏显示的唯一方式。场景配件可以让应用同时在多个显示屏上显示内容,并把附加内容和应用主界面配对。
一个直观例子是游戏:一块屏幕显示游戏画面,另一块屏幕显示控制器。主 UI 仍然负责主要流程,附加 UI 只承担与当前场景相关的操作。相机、演示和提词器也适合采用这个模式。

场景配件的可用性由系统动态控制。它们默认启用,但状态可以随时变化。应用要通过观察追踪响应可用性变化,让主界面和附加界面保持同步。不要把“已经注册过配件”当成“配件现在一定可见”。
CameraCaptureAccessory:相机的外屏辅助界面
CameraCaptureAccessory 是 iPhone Duo 上相机应用的一种新能力。它允许应用把额外 UI 放在外屏,同时把主 UI 留在内屏。拍照或录像时,被拍摄的人可以在外屏看到相关内容,而操作者仍在内屏控制相机。

这个配件并不是任何时候都可用。应用需要在内屏处于全屏模式,并且拥有活跃的相机会话。注册时,应把配件注册在与相机 UI 相同的视图上。这样,辅助内容和相机界面的生命周期保持一致,不会在离开相机功能后仍然出现在外屏。
用 sceneAccessory 做提词器
视频里的练习项目是一款相机应用,目标是在外屏显示提词器。做法很短:在相机视图上添加 sceneAccessory 修饰符,并在其中提供相机捕获辅助组件。由于配件注册在相机视图上,提词器只会在相机视图可见时显示。
当相机视图出现在内屏,提词器视图就会出现在外屏。主界面不需要复制一份完整相机 UI,外屏只放与当前拍摄有关的内容,这正是场景配件的价值。
接着可以在内屏工具栏里放一个按钮,切换提词器模型的启用状态,再把状态传给相机捕获辅助组件。配件不可用时,例如设备合上,按钮也应该禁用。给相机捕获配件添加 onAvailabilityChange 修饰符,就能通过回调监听这种变化。
把适配任务落到代码和测试上
这支 Tech Talks 的建议可以直接拆成四项待办:
- 在窄窗口和分屏状态下检查界面,优先修复内容被截断、控件不可操作的问题。
- 用
onHingeChange或UIHingeInteraction做一个小型交互实验,并为无铰链设备保留默认逻辑。 - 检查多场景入口,确认外屏不会提供无法创建新窗口的操作,并处理
UIWindowSceneActivationAction的失败情况。 - 为适合跨屏的功能注册场景配件,监听
onAvailabilityChange,在设备合上或状态变化时同步禁用相关操作。
铰链 API 负责告诉应用设备正在怎么动,布局 API 负责告诉应用空间怎么分配,场景配件负责把配套内容送到另一块屏幕。按这个分工改造,iPhone Duo 的两块屏幕才会成为同一个操作流程的一部分,而不是两份互相重复的界面。
系列文章
这套教程一共六篇,对应苹果官方的六支 Tech Talks 视频:





































