Highlight
macOS Monterey 为 Mac Catalyst 带来了四类原生 Mac 体验:四种按钮模式(Push/Toggle/Pull-down/Pop-up)、ToolTip 悬停提示、打印菜单集成、窗口副标题,让 iPad 应用在 Mac 上更像原生应用。
核心内容
按钮系统的 Mac 化
Mac 用户习惯了特定的按钮交互方式:Push Button 按下执行、Toggle Button 切换状态、Pull-down Menu 展开菜单、Pop-up Button 选择后标题跟随变化。iPad 应用直接搬到 Mac 上,按钮行为往往”不对味”。
macOS Monterey 通过两个属性解决了这个问题:showsMenuAsPrimaryAction 和 changesSelectionAsPrimaryAction。四个布尔组合对应四种按钮类型,代码只需几行。
悬停提示填补信息缺口
Mac 用户看到界面元素时,会本能地把鼠标悬停上去等待提示。iPad 应用没有这个功能,导致很多控件的含义要靠猜。
UIToolTipInteraction 让任何 UIView 都能显示悬停提示。UILabel 还支持 showsExpansionTextWhenTruncated,截断时悬停显示完整文本。
打印和窗口副标题
打印是 Mac 应用的基础功能。新增 UIApplicationSupportsPrintCommand plist 键自动添加 File > Print 菜单,printContent 响应者方法处理打印逻辑。
窗口副标题 scene.subtitle 为窗口标题栏增加上下文信息,比导航栏标题更符合 Mac 习惯。
详细内容
四种按钮配置(02:26)
// Push Button — 标准按下按钮
let pushButton = UIButton(type: .system)
// Toggle Button — 点击切换选中状态
let toggleButton = UIButton(type: .system)
toggleButton.changesSelectionAsPrimaryAction = true
// Pull-down Menu — 点击展开菜单
let pullDownButton = UIButton(type: .system)
pullDownButton.menu = UIMenu()
pullDownButton.showsMenuAsPrimaryAction = true
// Pop-up Button — 选择后按钮标题跟随变化
let popupButton = UIButton(type: .system)
popupButton.menu = UIMenu()
popupButton.showsMenuAsPrimaryAction = true
popupButton.changesSelectionAsPrimaryAction = true
关键点:
showsMenuAsPrimaryAction = true:左键直接展开菜单(Mac 习惯),不再依赖长按或右键changesSelectionAsPrimaryAction = true:按钮标题自动跟踪菜单中的选中项- 四种组合覆盖 Mac 上所有标准按钮类型
- 采用 Mac idiom 时,未配置菜单的按钮通过长按触发菜单;iPad idiom 则通过右键
为控件添加 ToolTip(03:50)
// 方式一:为任意 UIView 添加 ToolTip
let toolTipInteraction = UIToolTipInteraction(defaultToolTip: "Iguaçu Falls in Brazil")
imageView.addInteraction(toolTipInteraction)
// 方式二:为 UIControl 快速设置 ToolTip
let switchControl = UISwitch()
switchControl.toolTip = "Enable automatic updates"
// 方式三:截断标签悬停显示完整文本
let label = UILabel()
label.text = "Very long title that will be truncated"
label.showsExpansionTextWhenTruncated = true
关键点:
UIToolTipInteraction适用于任意 UIView,需要创建 interaction 对象- UIControl 的
toolTip属性是快捷方式,一行代码即可 showsExpansionTextWhenTruncated只在文本被截断时显示 ToolTip,保持界面整洁
窗口副标题(06:01)
// 在 scene 连接时设置副标题
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
scene.subtitle = "Countries"
}
// 或根据导航动态更新
func updateSubtitle(for selection: String) {
guard let scene = view.window?.windowScene else { return }
scene.subtitle = selection
}
关键点:
- 副标题显示在窗口标题栏,比导航栏标题更符合 Mac 设计规范
- 不同
toolbarStyle下副标题的显示位置不同,需要实验调整 - 适合展示当前选中项或应用状态上下文
打印支持(04:52)
先在 Info.plist 中添加:
<key>UIApplicationSupportsPrintCommand</key>
<true/>
然后通过响应者链处理打印:
// DetailViewController.swift
override func printContent(_ sender: Any?) {
let printInteractionController = UIPrintInteractionController.shared
// 配置打印内容
printInteractionController.present(animated: true)
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(self.printContent(_:)) {
// 当前有选中内容时才允许打印
return selectedItem != nil
}
return super.canPerformAction(action, withSender: sender)
}
// Root SplitViewController 中统一调度
override func target(forAction action: Selector, withSender sender: Any?) -> Any? {
switch action {
case #selector(UIResponder.printContent(_:)):
// 根据业务逻辑决定由哪个子控制器处理打印
return currentPrintTarget
default:
return super.target(forAction: action, withSender: sender)
}
}
关键点:
UIApplicationSupportsPrintCommand自动添加 File > Print 和 Export as PDF 菜单项printContent是 UIResponder 的新 action,通过响应者链查找实现canPerformAction控制当前状态下是否允许打印target(forAction:withSender:)在根控制器中统一调度,避免强制becomeFirstResponder
保持 iPad 按钮样式(07:34)
Mac idiom 默认使用原生 Mac 控件,但有时需要保持 iPad 风格的按钮(如大面积填充按钮):
let button = UIButton(configuration: .filled(), primaryAction: nil)
button.configuration?.image = UIImage(systemName: "leaf")
button.preferredBehavioralStyle = .pad
button.configuration?.preferredSymbolConfigurationForImage =
UIImage.SymbolConfiguration(pointSize: 60)
button.changesSelectionAsPrimaryAction = true
button.configurationUpdateHandler = colorUpdateHandler
关键点:
preferredBehavioralStyle = .pad强制使用 iPad 布局行为,按钮背景会拉伸填充- 仅在特定控件上使用,不建议全局采用
- 与 Mac idiom 的 77% 缩放规则不同,iPad 样式保持原始大小
核心启发
-
做什么:为现有的 iPad 笔记应用添加 Mac Catalyst 支持,用 ToolTip 展示工具栏按钮功能
- 为什么值得做:Mac 用户依赖悬停提示理解界面,添加 ToolTip 后应用 instantly 更像原生 Mac 应用
- 怎么开始:为每个工具栏按钮设置
toolTip属性,为截断的文档标题启用showsExpansionTextWhenTruncated
-
做什么:在 Mac 版文件管理应用中加入打印功能,支持打印当前选中的文件列表
- 为什么值得做:打印是 Mac 用户的基础预期,
UIApplicationSupportsPrintCommand一行 plist 配置就能添加标准菜单 - 怎么开始:添加 plist 键,在文件列表控制器中实现
printContent和canPerformAction
- 为什么值得做:打印是 Mac 用户的基础预期,
-
做什么:为 Mac 版设置应用使用 Pop-up Button 替代原来的 Segmented Control
- 为什么值得做:Pop-up Button 是 Mac 标准控件,比 Segmented Control 更节省空间且符合用户习惯
- 怎么开始:用
UIButton+changesSelectionAsPrimaryAction = true+showsMenuAsPrimaryAction = true创建 Pop-up Button
-
做什么:在 Mac 版浏览器/文件管理器中使用窗口副标题展示当前路径
- 为什么值得做:副标题比导航栏标题更符合 Mac 设计规范,且不占用内容区域空间
- 怎么开始:在
UISceneDelegate中设置scene.subtitle,在导航变化时更新
关联 Session
- Meet the UIKit button system — iOS 15 全新按钮系统,Mac Catalyst 按钮 API 的基础
- Qualities of a great Mac Catalyst app — 优秀 Mac Catalyst 应用的特质与优化方向
- Optimize the interface of your Mac Catalyst app — Mac Catalyst 界面优化深度指南
评论
GitHub Issues · utterances