大多数浏览器和
Developer App 均支持流媒体播放。
-
AppKit 的新功能
探索使用 AppKit 开发 Mac App 的最新改进。我们将向您介绍 SF Symbols 的最新更新,演示如何通过增强控制来优化您的界面,以及帮助您学习使用台前调度来整理窗口。我们还将讨论 macOS 的最新共享和协作功能等。
资源
相关视频
WWDC22
-
下载
♪ ♪
Jeff Nadeau: 大家好 欢迎收看 “AppKit 的新功能” 我是 Jeff Nadeau 是 AppKit 团队的一名工程师 我在这里和大家分享一下 为 macOS Ventura 构建 App 的 最新最棒的功能 对于 Mac 来说 这是一个 前所未有的激动人心的时刻 现在我们拥有 Apple 芯片的性能和效率 macOS 的力量 以及一个比以往任何时候 都更丰富的 App 生态系统 而您的 App 是这个故事的 重要组成部分 我们将继续推动 AppKit 发展 这样您们就可以继续构建 最好的 App 我将谈及各种各样的主题 从台前调度开始 接着是偏好设置 其次是各种控件 SF Symbols 和共享 我首先要聊一聊台前调度
台前调度会清理 工作区中的非活动窗口 而活动窗口会采取对象居中 对于更高级的工作流程 您还可以将窗口合并到一个 作为一组交换进出的集合中
这将影响您的 App 窗口的呈现方式 台前调度试图保持 工作区的整洁 所以当出现一个新窗口时 现有的窗口将退出 stage 以腾出空间 这就是“主”窗口 比如您的文档所需要的 辅助窗口 如面板 弹窗 设置和其他窗口 应该继续出现在现有窗口的上方 NSWindow 已经有了很多 API 可以帮助您定义 您想要特定窗口完成的行为
默认情况下 如果您显示一个浮动面板 一个模态窗口 或一个带有首选项样式工具栏的窗口 台前调度不会调出其他窗口
台前调度也会遵守窗口的 collectionBehavior 这个 OptionSet 定义了窗口在空间 和全屏中的行为方式 现在它还会帮助台前调度 理解窗口是被视为辅助还是浮动的 如果一个窗口的 collectionBehavior 包含辅助 moveToActiveSpace 固定的或暂态选项 那么它就不会将活动窗口 移到居中的位置 通过使用正确的收集行为设置窗口 您可以确保它们在每个情景中 都能很好地工作 无论是在桌面空间 全屏 还是现在在台前调度中 接下来 我将介绍偏好设置的 一些重要更改 在 macOS Ventura 中 “系统偏好设置”App 已采用了全新的外观 具有全新的导航方案 和全新的视觉设计 为了与其他操作系统的设置 保持一致 我们还将 App 重命名为 “系统设置” 这些更改也会扩展到您的 App 例如 今天的 “系统偏好设置”App 中 可能会出现一个首选项面板包 您的 App 中可能也有一个设置区域 它也有一个新的设计系统 用于控制丰富的表单 它可能是设置界面 或检查器的完美选择 如果您发布了一个自定义的预组件包 它将继续与新的“设置”App 一起运作 您的自定义面板将出现在侧边栏 App 会加载您的组件包 并显示您的设置 UI 如在 Monterey 中和早前一样 为了匹配新命名“系统设置”App 我们已将 App 内的首选项 重命名为“设置” 为了帮助您上手 一旦您使用最新的 SDK 进行构建 AppKit 将自动更新 App 菜单中的 偏好设置菜单项的名称 不过 您可能会在很多其他地方 使用 Preferences (偏好设置) 这个词 比如在窗口标题 描述性标签 或 App 周围的其他控件上 搜索本地化文本 找到同样需要更新的地方
例如 TextEdit 的设置窗口 过去被称为“偏好设置” 我们选择将该窗口重命名为“设置” 以匹配系统的其余部分 “系统设置”App 也使用了 一个新的界面样式 来显示它的所有配置选项 设置界面通常包含大量控件 因此这种样式旨在以清晰有序的方式 显示包含大量控件的表单
由于表单本身提供了大量的视觉结构 许多系统控件 通过使用较低的视觉权重 来适应这种环境 它们会同时在 rollover 上 展现出更突出的备份
如果您想编写使用这种新设计的接口 SwiftUI 会让它变得非常简单 将您的控件放到 Form 视图中 然后应用 insetGrouped 表单样式 SwiftUI 会负责剩下的事情 表单的视觉样式 滚动行为 和布局都会自动应用
如果您还没有开始使用 SwiftUI 这是个尝试一下的好机会 Settings 窗口通常是 App 界面的一个独立区域 所以它是进行 incremental adoption 的完美场所 我们甚至制作了一个关于同时使用 SwiftUI 和 AppKit 的视频 它可以让您进行深入了解 接下来 我想分享 我们控件的一些更新 我们有很多令人兴奋的控件增强 值得分享 首先是一个叫做 NSComboButton 的新控件 我们还更新了 NSColorWell 对 NSToolbar API 做了一些增强 调整了 NSAlert 的设计 改善了 NSTableView 的性能 首先是 NSComboButton NSComboButton 的主旨在于 结合一个即时按钮动作 和一个有附加选项的菜单
在今天的控件视图中 传统上 人们使用按钮 来执行一些即时操作 或者使用下拉按钮来显示 带有多个选项的菜单 NSComboButton 将两个元素 组合成了一个控件 它将主操作和下拉菜单 结合在了一起 这种设计通常用于像 Mail 这样的用例 这样 要获取预估的文件夹 就只需单击一下即可 但您仍然可以访问菜单 来将消息归档到任何地方 以前 您可能已经使用分段控件 API 组装过类似的东西 但现在有了专门的控件做这件事 NSComboButton 有两种样式 分别规定了按钮的外观和行为 默认样式称为 split 它包括一个只用于菜单的 单独的箭头部分
第二种样式是 unified 看起来更像一个普通的按钮 此样式在单击时执行其主要操作 如果单击并按住它 则会显示其菜单 这就是 NSComboButton NSColorWell 也有一些 很棒的新的更新 首先是一个全新的外观 现在颜色很好地采用了一种新风格 取代了经典的方形渐变外观 并让人能联想到整个系统的 其他按钮外壳 这个更改是完全自动的 因此您不需要采取任何措施 来获得这个新版外观 然而 我们知道颜色选择 是有创造性的 专业 App 的重要组成部分 所以我们更进一步 为 NSColorWell 引入了两种新的样式
第一种是最小样式 它在 rollover 上会显示一个披露箭头 并用弹出完整的 NSColorPanel 选项 通过显示可以立即从调色板中 进行选择的弹出窗口 来提供一个快速的颜色选择体验 默认情况下 它会使用系统标准的颜色网格 但如果您有不同的 UI 或调色板 您可以自定义这里显示的内容
第二种是扩展样式 您可以在 iWork App 中看到 这种风格结合了两种交互模型 左边的键有相同的披露箭头 和用于快速选择的弹出窗口 而右边的按钮可以拉出整个面板 以进行更细致的颜色选择
有了这个 NSColorWell 现在 能提供三种不同的选择颜色的方式
您可以使用 NSColorWell 上的 新 colorWellStyle 属性访问这些样式 它有每个样式的案例 默认 扩展和最小
NSColorWel 也因其 pulldown action 获得了一个新的目标-操作对 该操作会确定当您单击 最小或扩展颜色的下拉部分时 会发生什么 默认情况下 这些属性是 nil 这意味着 NSColorWell 应该使用系统标准的弹出窗口 但是 您可以自定义此操作 并用它来显示您自己的 自定义弹出窗口 或者您甚至可以显示一个 不同的选择界面 如菜单 这就是新的 NSColorWell 它有一个全新的外观 和两种快速挑选颜色的新方法 接下来是一些 关于 NSToolbar 的新闻 我们对它进行了各种 API 增强 让您更好地控制自定义 并增加布局的灵活性 在自定义方面 我们添加了两个新的委托方法 让您更好地控制工具栏的可自定义性 首先是 toolbar immovable item identifiers 如果您执行此方法 以返回一组项目标识符 那么这些项目 将不能被用户移动或移除 并且当您进入自定义模式时 它们不会显示动画
例如“邮件”App 希望过滤按钮 一直出现在这里 在消息列表的上方 通过使用这个 API 它们可以防止它被从这个位置移走
第二种方法称为“toolbaritem identifier can be inserted at” 此委托方法让您可以 对工具栏中任何特定的重新排序 插入 或删除操作行使否决权 您可以使用它来实现自己的 自定义规则 例如 您可以创建一个工具栏项 使它在工具栏的一个部分中被允许 但在另一个部分中被禁用
现在您可以使用新的 centeredItemIdentifiers 属性 为工具栏指定多个居中项 如果工具栏是可自定义的 那么您就仍可以从工具栏中 添加或删除此集中的项 但您只能在居中的组中 对它们进行重新排序 在这个例子中 所有的照片编辑工具 都集中在工具栏的中心 而与前后有多少项无关 一旦您按喜欢的方式自定义了工具栏 您不会希望项目到处移动 而这对于根据其他状态 改变含义的工具栏项目来说 是很困难的 比如“邮件”中的静音和取消静音按钮 它们在轻点后会互相切换
由于标签有不同的大小 工具栏中的其他项必须四处移动 以适应变动
在这样的场景中 您可以用 NSToolbarItem 上 新的 possibleLabels 属性来提供一组 将用于该项的本地化字符串
NSToolbar 会自动调整条目的大小 以适应最长的标签 因此 即使重新配置条目 您的布局也会保持不变 接下来 是对警报设计的更新 macOS 上的警报使用紧凑的布局 它经过了针对有几个明确选择的 少量文本的优化 总的来说 这是一个很好的 组合警报的方式 警报最适合较短的文本 您可以更直接地传达信息 而且人们更有可能在 越过警报进行下一步前 阅读您写的内容
然而 有时您确实无法缩短描述 尤其是在需要传达一些 复杂而微妙的信息时 比如这个 Disk Utility 警报 它传达了一个关于文件系统数据的 非常重要的选择 紧凑的布局并不适合这种情况 对于这些情况 我们调整了 NSAlert 以提供适合较长文本的更宽的布局 当提示文本太长 而无法容纳在紧凑的尺寸中时 这种调整会自动发生 如果附属视图太大 无法放进紧凑的警报窗口 我们也会使用这种样式 您的 App 不需要选择这个行为 它会在整个系统范围自动应用 需要注意的是 布局是在显示警报时确定的 因此 如果警报已经显示在屏幕上 则样式无法切换
您仍然应该尽可能地 减短警报文本的长度 但这个设计更新将改善那些 您无法减短文本长度时的用户体验
接下来是 NSTableView 的一个重要新功能 NSTableView 旨在通过在滚动时惰性填充 和重用视图来高效地处理大量的行 但是 对于每一行 都有不同高度的表来说 这是一个挑战 因为为了提供良好的滚动体验 表格需要知道它的总高度 以及每一行在滚动区域中的位置
过去 NSTableView 通过调整 表中所有行的大小来实现这一点 而这可能会对初始加载时间产生影响 在 macOS Ventura 中 NSTableView 实现了这些目标 同时提供了更好的性能
NSTableView 不再即时计算 每一行的高度 而是根据滚动视口内 或附近的行惰性来计算行高度
对于那些没有被测量的行 NSTableView 使用的是一个 基于它已经测量的行高度 得出的运行估计高度 当您滚动表格时 NSTableView 根据需要 来请求行高度 用实际测量值替换估计高度 同时会注意保持正确的滚动位置
这种优化显著改善了 过大的表的加载时间 这个变化改变了 table view: height of row 之类的 委托调用的时间 所以您不应该假设 NSTableView 何时会向您请求行高
这个优化同时适用于 NSTableView 和 SwiftUI 的 List 视图 并且自动用于 macOS Ventura 上的 所有 App 无需采用 这就是 NSTableView 的功能 接下来是 SF Symbols 的一些更新 macOS Ventura 包括 SF Symbols 4 它增加了超过 450 个新符号图像 涵盖了各种主题
这些新符号包括桂冠 各种家居用品 世界各地的货币符号 甚至各种与体育相关的符号 有了数以千计的符号目录 SF symbols 很可能包含了 可以代表您想表达的任何想法的 专业设计的图标 但我们没有止步于此 SF Symbols 4 还包括一些新的功能 以进一步增强您的图标 总结一下 符号图像支持多种呈现模式 您可以依据自己的设计来选择 它有使用一种颜色的单色呈现 使用不同颜色的不透明度来强调 符号某些部分的分层呈现 有允许您为符号的每个部分 指定不同颜色的调色呈现 以及使用直接设计到 符号作品颜色的多色呈现
这些选择使您能够灵活地 实现各种各样的设计 但我们也希望符号图像 在不需要应用任何配置的情况下 就能完美呈现
因此我们在 macOS Ventura 中 为符号引入了一个新功能 首选呈现模式 有了首选呈现模式 符号就可以明确 它们选择的呈现样式 在运行时 AppKit 将自动使用该样式 这对于像 AirPods Pro 这样更倾向于 用分层呈现来增加细节清晰度的 符号来说 是非常棒的 当然 如果您有不同的设计思路 您就随时可以使用 NSImageSymbolConfiguration 对象 来选择您喜欢的样式
有些符号不只是代表一个概念 它们还要传达一些值或数量 比如 Wi-Fi 信号强度或音频音量 对于这样的情况 我们引入了一种新的符号类型 我们称之为 variable symbol 使用变量符号 可以直接向 NSImage 提供一个浮点值 该符号会嵌入数值阈值 来决定每个路径 应该如何根据该值变化 这是 API 变量符号由新的初始化器创建 它类似于现有的符号图像初始化器 只是增加了一个 0 到 1 之间的浮点数作为值参数 如果符号图像没有定义任何可变阈值 则该值将被忽略 符号将按照正常方式绘制 如果是这样 您将发现符号路径 根据您提供的值而有不同的绘制
每个变量符号 都可以以自己独特的方式表示值 通过在 API 级别提供该值 您可以访问所有这些变量 而不必了解符号组成方式的细节
可变符号与呈现样式 如调色板和多色 结合使用效果很好 所以您可以将它们应用到 几乎任何设计中 最后 我想谈谈关于 “共享”的一些重大更新 macOS Ventura 提升了 Mac 上的分享体验 引入了如建议用户 以及邀请和管理合作用户的新方法 等功能 您可以采用一些新的 API 以便您的 App 能够最大限度地 利用这些增强功能
分享体验中最显著的更新 是新的分享弹窗 它用一个丰富的界面 取代了现有的共享菜单 它包含更多 关于您正在共享的文档的信息 以及熟悉的功能 比如推荐用户 它与前一个选择器支持相同的 API 和委托方法 因此您仍然可以进行 如过滤共享服务列表 或将您自己的自定义服务插入到 选择器中之类的操作
如果您正在共享一个文件 URL nsshareingservicepicker 可以自动为 Header 填充图标 名称 和其他关于文件的元数据 但是如果您要共享一个自定义类型 您可以让您的条目 符合 NSSharingServicePicker 请求那个信息所用的新协议
这个协议叫做 NSPreviewRepresentableActivityItem 符合类型必须能够返回 要共享的底层项 比如 NSItemProvider 它们还要能有选择地返回标题 图像提供程序和图标提供程序
为了方便起见 AppKit 中有一个符合规范的级 它叫做 NSPreviewRepresentingActivityItem 您可以用它来绑定一个现有的 共享项及其元数据 您可以直接以 NSImage 的形式 提供每个图像参数 如果预先生成这些图像 对性能要求太高 您也可以使用 NSItemProvider
新的共享选择器非常适合 从工具栏按钮之类的地方 开始共享 但有时您会想从菜单 比如主菜单栏或 App 内 选定视图的对应菜单开始共享 以前 您可能会通过枚举共享服务 然后为每个共享服务构建菜单项 构建自己的菜单来处理这个问题 虽然这确实有效 但它绕过了标准选择器 这样您就错过了所有这些新功能 在 macOS Ventura 中 NSSharingServicePicker 可以为您创建一个 standard share menu item 您可以将标准项目添加到任何菜单 轻松开始共享 一旦被选中 菜单项就会调用共享弹出窗口 对于特定情景菜单 它甚至会将弹出窗口 固定到生成菜单的视图 在 macOS Ventura 中 有很多管理协作的新支持项 通过一些额外的采用 您的可分享项目也可以 成为合作邀请 用户可以通过共享选择器发起 拖拽到 Messages 信息中 甚至通过 FaceTime 通话做到这些 您可以使用 CloudKit 或 iCloud Drive 来共享内容 也可以将邀请流程 与您自己的协作服务器连接 这是一个牵涉很广的话题 所以我们做了几个视频 来更深入地解释它 如果您的 App 支持协作 或者您想开始添加协作 一定要看看它们 开始使用 macOS Ventura 时 请确保您将窗口设置为 与台前调度最适合的状态 然后 考虑一下您的设计 会如何从 NSComboButton 和 NSColorWell 这样的控件 增强中受益 使用 SF Symbols 的最新符号 和功能改善您的图标 最后 对于协作 采用最新的 API 以便您最大限度地 利用 macOS Ventura 的新共享体验
感谢收看 也感谢您 持续开发好用的 Mac App
-
-
4:54 - Using the grouped form style in SwiftUI
enum AirDropVisbility: String, CaseIterable, Identifiable { case nobody = "No One" case contactsOnly = "Contacts Only" case everyone = "Everyone" var id: String { rawValue } var label: String { rawValue } var symbolName: String { switch self { case .nobody: return "person.crop.circle.badge.xmark" case .contactsOnly: return "person.2.circle" case .everyone: return "person.crop.circle.badge.checkmark" } } } struct ExampleFormView: View { @State private var name: String = "Mac Studio" @State private var screenSharingEnabled: Bool = true @State private var fileSharingEnabled: Bool = false @State private var airdropVisibility = AirDropVisbility.contactsOnly var body: some View { Form { TextField("Computer Name", text: $name) Toggle("Screen Sharing", isOn: $screenSharingEnabled) Toggle("File Sharing", isOn: $fileSharingEnabled) Picker("AirDrop", selection: $airdropVisibility) { ForEach(AirDropVisbility.allCases) { Label($0.label, systemImage: $0.symbolName) .labelStyle(.titleAndIcon) .tag($0) } } } .formStyle(.grouped) } }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。