Highlight
macOS Big Sur 让 Mac Catalyst 可链接更多 iOS 框架,加入硬件键盘、焦点、窗口行为和 Big Sur 外观支持,并用 Optimized for Mac 与 Universal Purchase 降低 iPad app 登上 Mac 的改造成本。
核心内容
把 iPad app 带到 Mac,第一步通常能跑起来。Catalina 时代的 Mac Catalyst 已经能让 app 使用更大的屏幕、添加工具栏和菜单,也会自动获得一部分 macOS 外观。真正的麻烦出现在继续打磨时:有些 iOS framework 不能链接,键盘和焦点行为不够桌面化,多窗口生命周期和 iPad 的直觉也不完全相同。
Big Sur 的更新先解决兼容性。Apple 在这一年把更多 iOS framework 带到 Mac Catalyst,甚至把一些 macOS 本身没有的 iOS framework 放进 macOS SDK,目标是减少为 Mac target 条件排除代码的需求。演讲里的例子是 ARKit:面向 Big Sur 或更新系统时,Catalyst app 可以链接 ARKit,再像在不支持 AR 的 iOS 设备上一样用运行时检查决定是否开启 AR 功能。
第二层是输入和窗口行为。UIKit 新增的硬件键盘事件、focus engine、selectionFollowsFocus、NSCursor、颜色选择器、日期选择器、菜单按钮、sheet、popover 和三栏 UISplitViewController,都让 Catalyst app 更接近用户对 Mac app 的预期。开发者仍然写 UIKit,但得到的是标准右键菜单、Mac color picker、AppKit inline date picker 和更像 Mac 的 sidebar。
最后一层是产品发布和界面质量。Optimized for Mac 把默认缩放从 77% 改到 100%,让文字和图形更清晰,也让控件度量更接近 Mac。SwiftUI 的 commands 和 toolbar 可以自然进入 Mac 主菜单和工具栏。Universal Purchase 则把 iOS 与 Mac 的购买关系合到一起,新 Catalyst app 默认加入,老项目或非 Catalyst Mac app 可以按文档迁移。
详细内容
1. 更多 iOS framework 可以直接参与 Catalyst 构建
(01:00)Catalyst 早期的一个痛点是 framework availability。演讲指出,过去依赖 ARKit 的 app 需要从 macOS target 移除 framework,并用条件编译避开 ARKit symbol。Big Sur 之后,Catalyst app 可以链接这些 framework,再用运行时能力检查控制功能入口。
import ARKit
if ARWorldTrackingConfiguration.isSupported {
showAREntryPoint()
} else {
hideAREntryPoint()
}
关键点:
import ARKit对应演讲中“可以链接 ARKit”的变化。ARWorldTrackingConfiguration.isSupported是运行时能力检查,适合判断当前 Mac 是否能开启 AR 功能。showAREntryPoint()和hideAREntryPoint()代表产品层的开关,避免把不支持的入口暴露给用户。- 这种写法把差异放在运行时,减少 Mac target 上的大段条件排除代码。
2. 键盘焦点和原始按键事件进入 UIKit 路径
(02:12)硬件键盘事件可以通过 responder chain 处理。演讲点名的入口是 pressesBegan 和 pressesEnded。游戏和画布类 app 可以用它们把方向键、修饰键和持续按压行为接到已有 UIKit 控制器中。
(03:01)同一段还提到 focus engine。UITableView 和 UICollectionView 可以让选择跟随键盘焦点。例如 sidebar 用方向键移动时,用户看到的焦点和当前选中项应保持同步;详情区则可以把方向键视为高亮移动,按 Enter 或空格再触发选择。
final class SidebarViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.selectionFollowsFocus = true
}
override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
for press in presses {
switch press.key?.keyCode {
case .keyboardUpArrow:
moveSelection(delta: -1)
case .keyboardDownArrow:
moveSelection(delta: 1)
default:
super.pressesBegan(presses, with: event)
}
}
}
override func pressesEnded(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
stopKeyboardDrivenMovement()
}
private func moveSelection(delta: Int) {}
private func stopKeyboardDrivenMovement() {}
}
关键点:
tableView.selectionFollowsFocus = true对齐演讲中“方向键在 sidebar cell 之间移动”的场景。pressesBegan(_:with:)在按键按下时进入 responder chain,适合启动持续移动。pressesEnded(_:with:)在按键释放时停止动作,避免用户松开方向键后界面继续移动。super.pressesBegan保留系统对其他按键的处理机会。
3. Scene 激活可以控制新 tab 和新窗口
(03:26)UIScene.ActivationRequestOptions 的 collectionJoinBehavior 属性让 Catalyst app 在激活 scene 时指定窗口创建行为,这个属性的类型是 UISceneCollectionJoinBehavior。开发者可以让新 scene 加入现有窗口集合,形成新 tab;也可以要求创建新的顶层窗口。
let options = UIScene.ActivationRequestOptions()
options.collectionJoinBehavior = .preferred
UIApplication.shared.requestSceneSessionActivation(
nil,
userActivity: userActivity,
options: options,
errorHandler: nil
)
关键点:
UIScene.ActivationRequestOptions对应演讲中的 scene activation 配置对象。collectionJoinBehavior = .preferred表示优先加入兼容的窗口集合,适合把内容打开为 tab。- 需要顶层窗口时,可以把行为改成
.disallowed,让 scene 创建新的 collection。 - 这个 API 把 Mac 上“tab 还是新窗口”的选择放回 UIKit scene 生命周期里。
(08:54)生命周期也有变化。Big Sur 会在更多场景让 scene 进入 background,例如窗口最小化、所在 space 离开视野、app 被隐藏。app 只要仍有一个窗口处于 foreground,或 app 控制着菜单栏,整体 app 状态仍保持 foreground。游戏和实时内容 app 需要按 scene 级别判断是否暂停。
4. 扩展和购买关系更接近 iOS
(10:20)Photo editing extension 可以带到 Mac。Catalyst extension 也获得更接近 iOS 的生命周期:不用时进入 suspended,需要时立即恢复,并应用 iOS 风格的内存限制和内存压力控制。WidgetKit 的 iPad widget 也可以通过 opt in to Mac Catalyst 运行在 Mac。
(11:15)Universal Purchase 解决的是用户购买路径。用户购买一个 Universal Purchase app 后,可以在所有平台访问。新的 Mac Catalyst app 默认加入 Universal Purchase;如果要退出,可以在项目设置里取消 “Use iOS Bundle Identifier”。老 Catalyst app、非 Catalyst Mac app 和既有 iOS app 的合并路径,需要按 “Offering Universal Purchase” 文档操作。
关键点:
- Photo editing extension 和 WidgetKit widget 都是现有 iPad 资产进入 Mac 的入口。
- extension 的 suspended/unsuspended 行为减少了开发者为 Mac 单独处理生命周期的压力。
- Universal Purchase 把商业模型从“Mac 另买一次”改成跨平台权益。
- 迁移老项目时,先核对 bundle identifier、capabilities 和 App Store metadata 的归属关系。
5. Big Sur 外观会自动覆盖一批 Catalyst 界面
(12:10)Big Sur 的新外观大量进入 Catalyst app。toolbar styles 可以通过 UITitlebar 的 toolbarStyle 属性设置 UITitlebarToolbarStyle,应用到每个窗口的 titlebar。separator identifiers 可以放进 toolbarDefaultItemIdentifiers,用于把 toolbar item 分配到 sidebar、内容区和右侧区域。accent color 则来自 asset catalog 中的 symbolic color,并作为 app-wide default tint color 使用。
if let titlebar = view.window?.windowScene?.titlebar {
titlebar.toolbarStyle = .unified
}
关键点:
windowScene.titlebar是 Catalyst app 访问 Mac titlebar 的 UIKit 入口。toolbarStyle = .unified对齐 Big Sur 统一工具栏外观。- toolbar separator identifiers 和 accent color 不需要改写整套 UIKit 布局,但需要开发者审查现有 toolbar 与资源目录。
- 演讲还提到 sidebar 中 collection view 的自动 drag reordering,采用 List Layout 的 app 可以直接获得更 Mac-like 的侧边栏行为。
核心启发
-
做一个键盘优先的 Mac 版资料库:把 iPad 上的列表/详情 app 改成三栏 sidebar,方向键驱动
selectionFollowsFocus,Enter 或空格触发详情选择。为什么值得做:这正是演讲中 sidebar 和 focus engine 的目标场景。怎么开始:先把主导航迁移到UISplitViewController三栏结构,再给 table view 或 collection view 加上焦点跟随选择。 -
给绘图、游戏或媒体 app 增加原始键盘控制:方向键移动对象,空格播放/暂停,修饰键改变拖拽行为。为什么值得做:Mac 用户会自然寻找键盘和鼠标路径,
pressesBegan、pressesEnded和NSCursor让 UIKit app 可以处理这些输入。怎么开始:从最常用的一组按键开始接入 responder chain,再把鼠标区域的 cursor image 配好。 -
把现有照片编辑能力做成 Mac extension:让 iPad 上已有的 photo editing extension 在 Mac 上可用。为什么值得做:Catalyst extension 会自动获得更接近 iOS 的 suspended 生命周期和内存压力行为。怎么开始:先为 extension target opt in to Mac Catalyst,再用 Instruments 和内存压力测试确认大图处理路径。
-
为付费 iPad 工具补齐 Universal Purchase:让老用户在 Mac 上直接获得同一份 app 权益。为什么值得做:演讲明确把 Universal Purchase 作为 Catalyst 上 Mac 发布的关键变化。怎么开始:核对项目里的 “Use iOS Bundle Identifier”,再按 Offering Universal Purchase 文档合并 capabilities 和 App Store metadata。
-
做一次 Big Sur 外观审计:检查 toolbar style、accent color、SF Symbols、color picker、date picker、pull-down menu、sheet 和 popover。为什么值得做:这批 UI 更新很多会自动生效,但 toolbar 分区、品牌色和旧自定义控件仍需要人工判断。怎么开始:先在 Big Sur 目标系统上跑现有 Catalyst app,把每个窗口的 titlebar、sidebar、表单控件和弹出层列成检查清单。
关联 Session
- Optimize the interface of your Mac Catalyst app — 深入讲解 Optimized for Mac、Mac idiom、1:1 渲染、Mac 控件外观和 Catalyst 布局迁移。
- Adopt the new look of macOS — 解释 Big Sur 的 sidebar、toolbar、accent color、控件和 SF Symbols 变化,是本 session UI 部分的 Mac 端背景。
- Build with iOS pickers, menus and actions — 展开本 session 提到的 color picker、date picker、pull-down menu 和 UIAction。
- Support hardware keyboards in your app — 深入讲解硬件键盘、responder chain、快捷键和原始按键事件。
- Accessibility design for Mac Catalyst — 从可访问性角度补充 Mac Catalyst 的键盘焦点、快捷键、分组和测试流程。
评论
GitHub Issues · utterances