关于 iphone-duo-readiness
iphone-duo-readiness 是帮助 iOS 开发者为 iPhone Duo 调整现有应用的技能。它通过检查空间假设、安全区域和系统容器,并引导模拟器验证及专项技能交接,覆盖从适配到发布准备的流程。
主要功能
- 01核查 SDK 与部署目标适配层级
- 02查找固定方向、尺寸与边距假设
- 03采用可适应的系统容器与安全区域
- 04通过模拟器和镜像检查不同姿态
- 05按应用需求转交专项技能
适用场景
- 01评估现有应用在 iPhone Duo 上的适配情况
- 02定位折叠或分屏时的布局缺陷
- 03规划工具栏、双窗格或相机专项调整
- 04准备设备姿态截图与 App Store 页面
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mirzaaghazadeh/ iphone-duo-skills --skill iphone-duo-readiness安装后在 Claude Code 中输入/iphone-duo-readiness确认已加载。
详细介绍
为 iPhone Duo 做好 iOS App 的准备
iPhone Duo 是 Apple 首款可折叠 iPhone:外屏为 5.4 英寸,内屏为 7.6 英寸,二者共用相同的宽高比,并由铰链连接,用户可以将铰链停在任意角度。现有 iPhone App 无需更改即可运行,但看起来会像是从未针对这种设备形态考虑过。
本技能是入门指引。按照清单逐项检查,然后根据 App 的实际功能,将后续工作交给相应的专项技能。
需要牢记的一个理念
iPhone Duo 不是一种新的交互范式,而是尺寸范围更广的连续谱。
移植中出现的每个问题,都源于 App 断言了某些固定条件:这种设备形态、这种方向、这个屏幕、这个宽度、这种对称边距。每项修复的思路都相同——将断言改为针对当前实际可用空间的问题。
如果你发现自己在编写表示“如果是 iPhone Duo”的分支,请停下来。改为根据尺寸类别或可用空间编写分支,这样在 iPad、分屏、iPhone 镜像,以及未来推出的任何设备上都会正确运行。
步骤 1 — 确定基准情况
先确认 App 是针对什么版本构建的,因为 SDK 是关键门槛:
| 构建所用版本 | 在 iPhone Duo 上的表现 |
|---|---|
| iOS 26 SDK 或更早版本 | 可以运行,但不会适配。展开时,App 会居中显示,周围留有空白。合上时,内容会显示在状态栏和摄像头的左侧。 |
| iOS 27 SDK | 会调整大小以填满大部分内屏,但仍会避开右侧边缘的状态栏。 |
| iOS 27.1 SDK 或更高版本 | 会延伸至整个屏幕,工具栏和标签栏会垂直排列在状态栏下方。解锁保留区域和排列 API。 |
检查项目中的部署目标和 SDK,然后明确说明 App 属于哪个级别。升级到 27.1 级别是收益最高的一项改动;本技能中的几乎所有其他内容都以此为前提。
在以 27.1 级别发布前,有一点需要注意:从这个级别开始,栏会改为垂直排列,因此发布前请确认内容可以适配。未检查就跨级升级,可能导致控件与 App 自身布局重叠。
让工具先做第一轮检查
Xcode 附带 App Resizability 技能(由 App modernization 技能更名而来;现在涵盖 SwiftUI 和 iPhone Duo)。在 Xcode 中,让编码助手执行 get my app ready for iPhone Duo,它会扫描步骤 2 中的模式,逐一解释并提出修复方案。
不使用 Xcode 助手?导出该技能并在其他 Agent 中使用:
xcrun agent skills export
它能发现大多数问题,但并非全部,因此之后仍需手动检查步骤 2。
然后查看实际运行效果
以下三种工具的保真度依次提高:
- Device Hub 中的 iOS 可调整大小模拟器——最快找出在任意尺寸下会出现问题的布局。
- macOS 27 上的 iPhone 镜像——将窗口朝两个方向都调整到极限尺寸,适合发现缓存尺寸相关的问题。
- Xcode 27.1 中的 iPhone Duo 模拟器——这是唯一能让你体验真实设备的工具。进行展开、合上、旋转和折叠操作,并拖动 App 到一侧,使用主屏幕指示器尝试分屏。
这里的问题取决于视觉表现和设备形态,光看代码是找不出来的。
步骤 2 — 搜查固定假设
在代码库中搜索以下内容。每一项在这台设备上都是真实缺陷:
方向分支。 搜索 UIDevice.current.orientation、
statusBarOrientation 和 interfaceOrientation,包括
windowScene.effectiveGeometry.interfaceOrientation。内屏不遵循受支持的界面方向,而且方向已无法告诉你应用当前的显示形态。要判断宽度是否大于高度,请比较实际可用空间的宽和高:视图控制器中的 view.bounds、视图中的 superview.bounds,或 SwiftUI 中 GeometryReader 的尺寸。
UIScreen.main。 在双屏设备上含义不明确,而且即将弃用。每种用法都有对应的替代方案:
| 不要使用 | 改用 |
|---|---|
UIScreen.main.bounds | view.bounds / window.bounds;SwiftUI 中使用 GeometryReader 或 onGeometryChange |
UIScreen.main.scale | traitCollection.displayScale,或 @Environment(\.displayScale) |
UIWindow(frame: UIScreen.main.bounds) | UIWindow(windowScene:) |
存储 UIScreen | 按需读取 view.window?.windowScene?.screen |
读取尺寸一次后再缓存。 这一项很容易被忽略。在启动时或 viewIsAppearing 中读取尺寸并不足够,因为设备折叠时,应用会在会话进行中调整大小。依赖尺寸的布局应放在 layoutSubviews / viewDidLayoutSubviews 中;对于必须在尺寸变化时执行的工作,使用 viewWillTransition(to:with:)。
“常规宽度意味着 iPad。” 这是最容易导致屏幕明显错误的陷阱。许多应用在 horizontalSizeClass == .regular 时显示仅限 iPad 的布局,并假定 iPhone 始终是紧凑宽度。内屏为常规宽度,因此现在手机上也会运行该 iPad 布局。两个方向都要检查:在常规宽度下触发的分支,以及假定为紧凑宽度的分支。还有一项相关问题:删除任何与特定设备尺寸比较的代码,例如 bounds.height == 844 或已知 iPhone 尺寸表——这些都不适用于这台设备。
全出血媒体。 设置为 .scaleAspectFill 或 .aspectRatio(contentMode: .fill) 的主视觉图片和视频,在更宽的屏幕上会裁剪得更严重,甚至可能完全裁掉主体。根据当前尺寸类别或宽高比选择填充或适配,或者设置焦点。
对称内边距计算。 这是个隐蔽问题。在 iPhone Duo 上,安全区域和布局边距通常不对称——垂直控件只会出现在一侧,具体在哪一侧取决于设备姿态和分屏视图的位置。任何形如 bounds.width - safeAreaInsets.left * 2 的计算都是错误的。应使用全部边缘的内边距,让每条边分别发挥作用。
硬编码宽度和断点。 固定点值、设备宽度表、“如果宽度 > 390”之类的阈值。应针对两种尺寸类别:外屏为紧凑宽度,内屏为常规宽度。
手动实现的栏。 自定义 UIToolbar、UINavigationBar 或 UITabBar 不会参与系统的垂直栏布局,其内容也不会纳入其中。
步骤 3 — 采用标准容器
实现良好适配的最省力方式,就是让系统容器负责调整布局。以下容器已能充分适配各种姿态:
NavigationSplitView/UISplitViewController— 设备合上时,列会折叠为单列堆栈;打开时,则会平铺显示或作为叠层显示。TabView/UITabBarController— 能适配各种姿态,并在适当时改为垂直布局。在内屏上,可将标签栏的首选位置设为.sidebar,以启用更丰富的边栏。NavigationStack、List、ScrollView— 会自行适配为保留区域留出的空间。- 工作表、警告框、菜单、弹出框和上下文菜单 — 会自动调整位置以避开折叠处。
系统组件具备避让折叠区域的能力:它们会将交互元素移出弯曲区域,避免按钮落在折叠处。使用这些组件即可免费获得这一能力;如果不使用,就需要自行实现。
步骤 4 — 正确处理安全区域
按优先级排列的四条规则:
- 所有条状元素都使用容器提供的栏。它们会布局在安全区域之外,并自行避开状态栏、灵动岛和摄像头。横向栏会影响顶部/底部内边距;纵向栏会影响前导/尾随内边距。
- 让可交互且清晰可读的前景内容处于安全区域内。SwiftUI 默认会这样处理;在 UIKit 中,请参考
safeAreaInsets,或将视图约束到安全区域布局指南。 - 让背景延伸到安全区域之外——在 SwiftUI 中使用
.ignoresSafeArea(),在 UIKit 中使用view.bounds——让图稿延伸到栏和侧边栏下方。 - 独立处理每条边,并在分屏视图的左右两侧都进行测试。
对于需要位于安全区域之外、又不能与系统 UI 冲突的自定义 UI,iOS 27.1 新增了 ReservedRegion(SwiftUI)和 UIViewReservedRegion(UIKit)。应使用它们,而不是猜测内边距。
要匹配屏幕的圆角半径,请使用 iOS 26 的同心圆 API——SwiftUI 中的 ConcentricRectangle,UIKit 中的 UICornerConfiguration——它们已针对这款设备的形状进行了更新。
步骤 5 — 转交给专门工具
| 如果应用…… | 使用 |
|---|---|
| 有工具栏、标签栏或溢出菜单 | iphone-duo-vertical-bars |
| 有自定义布局、类似分屏的视图,或内容会落在折叠处 | iphone-duo-adaptive-layout |
| 需要由转轴驱动的效果、多窗口或双显示屏 UI | iphone-duo-hinge-and-scenes |
| 拍摄照片或视频 | iphone-duo-camera |
| 需要决定每个窗格中放什么、调整资源尺寸,或构建双窗格付费墙/引导流程 | iphone-duo-dual-pane-patterns |
| 需要进行设计审查,而非代码审查 | iphone-duo-design-review |
设备数据位于 ../../reference/device-facts.md;每个 API 名称及其所属框架都列在 ../../reference/api-index.md 中。
步骤 6 — 发布
适配应用是大部分工作,但 App Store 相关事项很容易被忽略,而且处理起来并不费事:
- 截屏和预览。 在不同方向和姿态下截取应用画面,让产品页面展示应用在这款设备上的实际运行效果,而不是将手机布局拉宽。请查看当前的截屏规格,确认所需尺寸。
- 徽章。 在 App Store Connect 中提交 iPhone Duo 截屏后,产品页面会显示徽章,标明应用已针对 iPhone Duo 优化。这样一来,截屏工作就不只是改善图稿,还能成为列表页上醒目的标识,因此这是本节中回报最高的一项。
- 发布前预览。 App Store Connect 提供预览工具,可检查资源在 iPhone Duo 上的呈现效果。值得一用——资源在 Xcode 中看起来合适,在产品页面上仍可能显示不佳。
- 推荐提名。 你可以通过 App Store Connect 提交一项提名,并在“Helpful Details”部分说明应用已针对 iPhone Duo 优化,包括支持所有设备姿态。尽早行动很重要:应用发布时,优化版应用不会很多,而这正是编辑团队关注的时机。
反馈结果
告知用户其所处的级别、找到的具体缺陷及对应的 file:line,以及哪些更改会提升级别。对于必须通过运行中的模拟器才能确认的问题,请如实说明——依赖设备姿态的布局缺陷无法通过静态检查判断,声称可以只会浪费用户的时间。
准确性说明
本仓库中的签名已于 2026 年 9 月 25 日对照 Apple 发布的 API 参考文档核验,因此不再是根据 Tech Talk 视频推测得出的。其中有三处说法不正确,并已在核验过程中修正——请参阅 ../../reference/api-index.md 中的 ⚠ 标记。
Apple 的 Prepare 检查清单此后也已发布,并一并纳入本文,因此现在的书面指南内容完整,不再是根据视频推断得出的。
但仍有一项注意事项,而且很重要:本文中的内容均未在真实设备上编译或运行。尤其是依赖姿势的布局行为,需要通过模拟器确认,因此不要仅凭文档就声称已验证。