View in English

  • Apple 开发者
    • 入门汇总

    探索“入门汇总”

    • 概览
    • 学习
    • Apple Developer Program

    及时了解最新动态

    • 最新动态
    • 开发者你好
    • 平台

    探索“平台”

    • Apple 平台
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    • App Store

    精选

    • 设计
    • 分发
    • 游戏
    • 配件
    • 网页
    • Home
    • CarPlay 车载
    • 技术

    探索“技术”

    • 概览
    • Xcode
    • Swift
    • SwiftUI

    精选

    • 辅助功能
    • App Intents
    • Apple 智能
    • 游戏
    • 机器学习与 AI
    • 安全性
    • Xcode Cloud
    • 社区

    探索“社区”

    • 概览
    • “与 Apple 会面交流”活动
    • 社区主导的活动
    • 开发者论坛
    • 开源

    精选

    • WWDC
    • Swift Student Challenge
    • 开发者故事
    • App Store 大奖
    • Apple 设计大奖
    • Apple Developer Centers
    • 文档

    探索“文档”

    • 文档库
    • 技术概述
    • 示例代码
    • 《人机界面指南》
    • 视频

    发布说明

    • 精选更新
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • Apple tvOS
    • Xcode
    • 下载

    探索“下载”

    • 所有下载
    • 操作系统
    • 应用程序
    • 设计资源

    精选

    • Xcode
    • TestFlight
    • 字体
    • SF Symbols
    • Icon Composer
    • 支持

    探索“支持”

    • 概览
    • 帮助指南
    • 开发者论坛
    • “反馈助理”
    • 联系我们

    精选

    • 《开发者账户帮助》
    • 《App 审核指南》
    • 《App Store Connect 帮助》
    • 即将实行的要求
    • 协议和准则
    • 系统状态
  • 快速链接

    • 活动
    • 新闻
    • 论坛
    • 示例代码
    • 视频
 

视频

打开菜单 关闭菜单
  • 专题
  • 所有视频
  • 关于

更多视频

  • 简介
  • 转写文稿
  • macOS 版 Cocoa 新功能

    深入了解 macOS 版 Cocoa 框架的最新功能。知晓深色模式、控制着色、触控栏和访达的上下文工作流,以及 AppKit、Foundation 及相关方面的其他改进。简要了解本年度讲述 Cocoa 功能改进的课程及相关指南。

    资源

      • 高清视频
      • 标清视频
    • 演示幻灯片 (PDF)

    相关视频

    WWDC18

    • TextKit 最佳做法
  • 搜索此视频…

    下午好 我的名字是 Ali Ozer 我和我的同事们 Chris Dreessen 和 Jesse Donaldson 将要一起为大家介绍 macOS Mojave Cocoa 的新功能

    如大家昨日所见 今年我们在 AppKit 新增了 一些惊人的新功能 我们将会谈到 如下的几个问题 我们将会讨论到 我们一直在做的 API 改进 令人惊艳的新的黑暗模式 以及相关的功能 在 layer backing 做出的一些改动 以及定制的快捷操作

    那么 让我们就进入这些内容的讲解吧 现在 正如你们知道的 我们对我们的 API 感到自豪 而且我们的目标一直是 希望 API 可以是有效的 连续的和强大的

    依据这个理念 我们一直在改进 提高 Objective-C 和 API 的 Swift exposure 而且 这不仅仅存在于 AppKit 或者 Foundation 其他的体系中 包括 UIKit 中也存在 以及你们今天早上可能也听到过的 Cocoa Touch 有什么新的改变

    现在 我们正在做的 API 的改变 在 Objective-C 是完全源头可兼容的 而且我们也期待 到我们 GM SDK 的时候 它们在 Swift 会是 100% 可移动的 那么 基于以上 让我们看一下 在此次的发布中 API 的一些改进 首先我要说一下 字符串种类的一些更新

    在上一个发布中 我们介绍了 字符串枚举种类作为一种方式 去一起搜集成群相关的 字符串常数 这些帮助 API 在这些种类中更加清晰

    以下是一些例子 第一个是 NS STRING ENUM 这被用于字符串枚举 枚举中 我们提供框架之外的 同时框架也无法进行扩展 因此是固定的一套值 旁边的这个 NS EXTENSIBLE STRING ENUM 是被用于 declare 字符串枚举 此处我们可以提供一些 box 之外的值 但其他的 框架和 App 也可以 加入到这组设定中 那么这里我们做了两个改变 第一个是简单的 我们很简单地用它们的 类型变体取代了 NS STRING ENUM 和 NS STRING EXTENSIBLE ENUM 这是一个很有效的误操作变更 这些更加常见的种类 的相同声明 因此 你的代码 调用站点或者任何东西 都不需要改变 下一个是 NSImageName 经历了更大一些的改变 一个更加显著的改变 与字符串枚举不同 它被声明是 NS SWIFT BRIDGED TYPEDEF 实际上是一个定义类型 现在 这就是 Swift 显示出来的样子

    在 Swift 4 中 NSImage.Name 作为结构 出现 这个结构就是 你声明字符串枚举的形式 在 Swift 4.2 中 它作为一个 TypeAlias 一个简单的 古老的 普通 TypeAlias 更加简单

    因此 问题就是 为什么我们要如此做呢 让我们来看看一个调用站点的例子

    这里在 Swift 4 中 就是你如何提取 一个字符串 使用命名方式在其中 创建一个 NSImage 的操作方式 在这里你可以看到 你会提取这个字符串 我们正将它转换成 一个 NSImage.Name 再变成 named 在 我们调用 NSImage named 之前 由于这里不得不重复 NSImage.Name 这种操作并没有特别流线型的体验 现在 由于 Swift 4.2 中的改变 这就是我们需要写入的所有 你无需一定要转换为 NSImage name 这种操作会更顺畅 更清晰一些 也会更少冗杂 因此我们相信这种定义类型 方式对于传递值更为合适 [ 掌声 ] 是的 我们也听到你们有些人说起来

    所以 我们相信这种方式 对于传递值 比如 resource names 或者标识符 更加合适 基本上而言 值并不会被 框架所体现 它们只是被用于一个传递的样式 图片名称 颜色名称 以及窗口框自动保存的名称等等 以及窗口框自动保存的名称的种类 现在 需要注意的是 即使是使用这种新方式 你们依然拥有特定的 API 所具有的好处 这是对 NSImage 命名方式的声明 你还要注意 这里讲的还是 NSImage.Name 与字符串截然相反 所以 我们仍然会遇到它 现在 这就是所有种类的清单 我们对 NSAppKit 也进行了这种操作 结果证明许多种类都能从中获益

    而且不仅仅是这一个 更是这一套 因此 许多种类在这个样式里面都发生了改变

    接下来 我要讲一下 一般的前缀 如你们在过去几年中所见 随着时间流逝 我们已经逐步从多年前使用的一般后缀 使用的一般后缀 转移到 Objective-C 中的一般前缀 使用一般前缀可以使得名字成组合 使得名字成组合 也会更容易被发现 并在 Swift 中遇到

    那么 让我们来看下面这个例子 这是 NSLineJoinStyle 出现在 10.13 SDK 这是它在 10.14 中显示的样子 你会发现枚举的值 比如说 MiterLineJoinStyle 现在已经变成了 LineJoinStyleMiter 所以 因为一个一般前缀 Swift 的显示从 miterLineJoinStyle 变成了只有 miter 因此 你可以看到 你不必 再重复输入 在调用站点体现得更为明显 更加清晰 体验这么好 此处需要一个笑脸的表情 [ 掌声 ] 谢谢

    同时 我们对很多之前没有进行过 这种改变的其他种类 也应用了此改变的特性 以下是这些种类的清单

    接下来 我想说的是 形式化的协议 在过去的时间里 我们用的是 非正式协议 主要就是 NSObject 上面的种类 将相关的方法 组合在一起 那时起 我们还增加了 一些功能 比如协议上的可选方法等等 我们也在可能的时候 将其转换成正式协议 下面 我将要给你们展示 我们操作的其中的 一个例子

    这就是这个方法 validateMenuItem 它曾是一个 非正式协议 在 10.13 中的一个分类对象 现在 它是一个正式协议 称为 NSMenuItemValidation 其中包含着方法 Swift 的显示从 一个扩展 NSObject 变成一个 正式协议 当然就是 Swift 4.2 中的 NSMenuItemValidation 当然了 这里的好处就是 执行菜单项目验证的对象 现在有了一种方式 可以正式声明 它们是遵照这个协议来进行操作的 我想再说一遍 我们很喜欢这样 对许多其他的 API 我们也做了这样的 改造 那么 这就是我们在 AppKit 中加入的 正式协议的全部清单 你会发现诸如颜色改变 字体改变 NSEditor NSEditorRegistration 将相关绑定的方法等等 组合在一起 这就是新的 正式协议的清单

    接下来 我想要说一说 直接的实例变量访问 目前 我们的 API 几乎所有的 实例变量 都是私密的 但是 我们已经说过 他们已经以某一种方式被声明 尤其是在一些比较老的 AppKit 类 子类被允许 接触到实例变量 直接获取到这些实例变量 现在 你们中的一些人甚至 没有意识到这个 所以请不要 直接找到然后开始使用 因为这可能是之前旧的代码 我敢肯定这些代码你都没有写过 可能是直接从前人那里获得的 这些代码可能会直接使用实例变量 所以 现在来讲 我们将会 对此操作明显地表达不赞成 并在之后弃用 现在 如果你直接通过代码获取到 实例变量 会收到一个警告 我们的想法是在未来的更新中 要切断这种操作 所以 如果你遇到了这种情况 请不要理它 直接删除这些使用

    改进的方式也非常直接 与直接获取 实例变量不同的是 你可以继续调用那些已经 有获得者或者 访问过的属性 或者其他可能的方式 或许 你有要获取这些 实例变量的原因 你也没有看到任何一个可以获取的方式 你或许可以告诉我们

    现在 说起弃用 我们还正在做另一件事

    叫作正式软弃用 这么多年来 我们已经弃用了 许多 API 的也使用更好的代替了它们 当弃用不紧急的时候 我们通常 会走非正式弃用的流程 我们会告知 API 要弃用 我们发布通知 对其进行标记 等等 在最终标记弃用之前 通常这种操作可以减少破坏 但是 我们有一种方式 要正式 对 API 进行弃用标记 我给大家举个例子

    这里我们有一个符号 NSBoxOldStyle 即将变成需要 被弃用的名字 你会发现我们已经 将其标记为弃用 它的版本号已经变成 API 即将弃用

    此举就是为了告诉编译器 不要产生一个 弃用警告或者错误 然而我们的目的是 如果你 Xcode 或新代码中 或者获取文件中 尝试使用这个符号 你会收到一个警告 警告此符号 已弃用 并且 指向新的代替的符号 当然了 同样也是在 Swift 中碰上 你要看这里 要提示的一点是 版本号 100,000 这不是一个提前的宣布 或者是未来的 SDK 的泄露 它只是一个占位符编码 我们目前用它来显示这个功能

    现在 我们在一些其他的 案例中也使用正式的软弃用

    更早之前我给你们展示过这个 并且 我告诉过你们我们重新命名了 MiterLineJoinStyle 变成 LineJoinStyleMiter 我还说了 Objective-C 源代码是 100% 兼容的 那么你可能会想知道 对于你重新命名的旧的符号 进行了什么操作呢 事实上 我们将那个你看到的旧富豪 使用了这个新的版本号标记 API TO BE DEPRECATED 因此 我们宣布其已被弃用 标记是 API TO BE DEPRECATED 意为着任何试图使用它的操作都会被警告 但已存在的使用会被保留 因为我们 不想真正的破坏 在 Objective-C 源代码中 这个符号的使用 现在 有许多符号等待着 被进行这种操作 因此许多会被标记为 API TO BE DEPRECATED 数目很多是因为 我们使用一般前缀取代一般 后缀的命名 还有一些是 其他的符号 我们 不再强调弃用 因为我们要引入新的来取代它们 尤其是支持 黑暗模式的功能 你们在今天的晚些时候会听到有关这一方面的内容 最后一个我想说的话题是 安全编码 你们可能有所了解 我们在 10.8 and iOS 6 引入了 完全编码 当你压缩的时候 基本上会允许你 确认什么样的类是你需要的 这样 如果在压缩文件中没有遇到这些 就会成为一个 明显的错误

    现在我们处理安全 编码的方式 是将其作为可选功能 但是 我们新的 API 既允许 安全编码作为默认动作 也允许其作为备选项 同时还可支持错误返回提示 我们的压缩和解压 API 会有一些例外 但是当然我们更偏向于错误返回 并且 新 API 激活的错误 返回动作是默认的

    因此 我将给你展示 API NSKeyedUnarchiver 因为这是其中最有意思的 这是一个 NSKeyedUnarchiver 其中一个新的方法在里面 它简单地创建了一个 keyedUnarchiver 非常安全地 并且用一种方式返回错误 其他两个新的方法 就是这些简便的 API unarchivedObject(ofClasses from 和 unarchivedObject(ofClass from 这些基本上解压了 单一个目标并返回 操作很安全 并且如果遇到问题 会返回错误 现在 说一下这里的第二个方法 这是一种装饰 就如张扬美丽的孔雀 所有的装饰帮助 Swift 更好地推断返回种类 这当然也是 Swift 擅长的操作 现在 要注意一下 在今年的 SDK 中被抛弃的功能 在 10.13 和 iOS 11 中仍可使用 所以 你可以开始会用他们 即使是通过那些调度目标

    这些方法 取代了这里这一页的方法 现在 你要注意这些是在 10.14 和 iOS 12 中 被弃用的 因为这些不是源编码的操作 我们会立刻弃用它们 而不是通过 正式软弃用的 因为我们真心希望能够 鼓励你们 转换到安全编码 如果你还没有开始的话

    现在 关于安全编码另一件事 是一个新的值转换器 你可能知道 NSValueTransformer 是一个类 用于自动将值做转换 从一个转换成为另一个 这里的两个 valueTransformers unarchiveFromData 和 keyedUnarchivedFromData 第一个进行无密码压缩 第二个进行 有密码压缩 但并不安全 因此 这些方法 并不是我们所喜欢的 所以我们要弃用这两个 然后使用这个新的安全的 Unarchive FromDataTransformerName 来替代它们 从而可以安全地解压 因此 我们也希望你们能尽快转换为这个 现在 在安全编码的前线 我们已经前进了不少 而且 在许多 Appkit 类中 新添加了安全编码 要注意这里 NSAppearance 最近已经 越来越明显地 成为你的朋友 在之后我们在 AppKit 中添加黑暗模式 及其他功能的演讲中也会遇到它 我们也在一些基础的 API 中加入了安全编码 这些 API 中此前都是没有安全编码的 下面这个就是列表

    还有另外一个关于安全编码的提醒 我们周四上午会有一个会议

    名为 你可以信任数据 会上我们会讨论 编程 压缩和解压缩 以一种稳健又安全的形式 我邀请你们去参加 在周四早上九点 现在 演讲下面的内容 将是关于 AppKit 的新功能以及相关的领域 因此 接下来我要请 Chris 上台给大家做讲解 [ 掌声 ] 多谢 Ali 黑暗模式是 macOS 10.14 版本 推出的最令人惊喜的功能之一 我估计大家昨天都已经一睹为快了 可能你们其中的一些人 现在正运行着这个模式 不过我们还是来一起看一看 我们提供了这些出色的 新系统图案 这使得我们系统的 UI 看起来很棒 这也会使你的 App 获得良好的视觉观感 也能保证你自创的用户内容有良好的视觉体现 我们想要知道的是 要兼容采用这个模式 都需要做什么呢 第一步其实是特别简单的 我们需要重新编译 macOS 10.14 SDK 这个挺简单的吧 其实做这一步对于我们来说就够了 但是大多数人 还是需要继续操作 再多做几步 才能让自己的 App 变得更加美观 下一步我们要操作的 就是需要在我们硬编码 颜色数值的存储地址检索 我们的 App 然后我们将它替换成一个 对外观敏感的颜色

    对于大多数的系统 UI 元素而言 AppKit 其实提供了 多种动态的系统颜色 可以和现有的外观互动 而且 不论你想要使用什么样的 UI 元素 视觉效果都会不错 并且 为了充实原有的系统颜色 我们在 macOS 10.14 中加入了 更多上述的颜色

    当然 有些情况下 你的操作对象不是系统 UI 元素 而是想要去 调整一些文档模式的部分 使它们能在黑暗模式中 表现得更加美观 现在你可以在素材目录中 整理你可以使用的颜色 当你使用 Xcode 中的 颜色编辑器时 你可以 自行配置和想要设置颜色 相对应的外观 只需要使用在右方的工具栏就可以 在这里 我们已经为 日光外观模式 黑暗外观模式 以及备用外观模式 都选择好了颜色 同颜色设置一样 接下来 让我们一起浏览一下 我们的 UI 系统 也找找我们可以应用 模板图像的地方 模板图像的奇妙之处 在于不论我们使用何种外观 我们选择的模板图片都能自动匹配出正确的颜色 例如 你可能在自己的 App 中 加入了一些深灰色的元素 或者纯黑色的元素 这些元素在日间模式下看起来 自然没有问题 但是在黑暗模式下就出问题了 因此呢 这时你就可以用编程方式使用模板图片 你也可以在资源目录里面自己设置 不过 你不需要 在创建你的黑暗模式 UI 时 把自己的思路限制在模板图片上 你也可以指定颜色 哦 对不起 是指定图片 指定在黑暗模式 显示不同的图片 比如 我们的 Planet App 我们需要在黑暗外观模式的时候 使北美这块区域更多呈现出夜晚的效果 但是在其它外观情况下 则需要使用日光 外观模式

    这里不得不提黑暗模式的最妙之处 就在于我们对 桌面图片的处理 大家可以通过我接下来的演示 更好地理解我说的这点 如果你只是粗略地看一下 系统偏好 UI 窗口 似乎看起来只是一个暗灰色 但是其实我们的系统偏好 UI 窗口 比第一眼看上去要复杂多了 我们来看一下这个窗口的后面 我们能够看到这极美的沙丘 而且还有 很多蓝色 很多光线 很多深灰色在那里 如果我们 要为这个长方形区域 选择一个平均的蒙板颜色 我们使用的是这个漂亮的深蓝色 所以 当我们创建 UI 然后再加回这个灰色颜色时 它不是纯灰色 我们还在里面保留了那个深蓝色 这个甚至在我们 再在窗口加回单个的控制器时 还会扩散开来 他们都从桌面图片中获得了这个很棒的特性 比如我们这次 想要使用另外一个桌面图片 比方说这个花朵背景的桌面 看到了吧 我们 的背景图片中有了更多亮紫色 亮绿色 这个也影响了系统 的偏好显示窗口 同理 如果我们在这里使用 一个红色的花朵做背景 大家也就能看到 系统偏好窗口从 这个桌面图片中获取了 这样的暖色调 并将这种暖色调适用到所有的 UI 元素之中 你们肯定会自然想到 要实现这个功能 听起来是要有很多动态的工作要做 才能确定窗口在哪里 平均的色彩是什么 然后再把这一切同步起来 其实 大家不要觉得这个工作量很大 而产生畏难情绪 AppKit 能够帮你搞定这些

    这里有很多大家都特别熟悉的类 能够帮助 我们把这些任务都 自动完成好 就是 Window ScrollView TableView 和 CollectionView 它们在黑暗模式下 不需要任何调整都能看起来很美观 当然了 如果你想要 亲自上手 你也可以 对它们进行微调 这些类都有 一个背景色属性 有四个特别的 NS 颜色是我想要多解释几句的 控制背景颜色 窗口背景颜色 页面下颜色 以及文本背景颜色 这四个 NS 颜色 在调用这些类的时候 都会有一些桌面图片元素的注入 都会随同你想要 创建的 UI 元素 相对应地看起来有些不同

    另一个我特别想要提到的类是 NSBox 类 当你想要配置成 用户个性风格的话 你可以使用填充颜色属性 来选择一个特殊的 NS 颜色 或者其它的 NS 颜色 这一点意义非常重大 你可以使用 NSBox 来 给你的 UI 的某一部分 加上颜色 而其它特殊情况下 这些类表现会更不同

    大家如果想要知道 更多细节的话 我想介绍 另一个 AppKit 类 这就是 NSVisualEffectView 另外 NSVisualEffectView 拥有材料属性 能够使你决定你使用的视觉效果如何 处理其后的背景 如何进行配色操作 我们需要多讲几句 才能让大家明白 在你的 UI 中 VisualEffectView 是如何运作的 在 macOS 10.14 中 我们做了更多的补充 所以 不论你要创建哪一种 UI 我们都有适合你 应用场景 在过去的 OS 版本里 大家都知道我们直接把一些材料属性 标记为 light 或者 dark 大家在新版本中都可以不使用这些 这些和许多新的外观 都不是特别适配 这就引出了我下一个话题 就是我们所说的强化色彩 我们来看看屏幕上的这些 UI 元素 这个视觉色彩确实很惊艳 这些元素看起来很棒对吧 在 macOS 10.14 我们还 添加了更多的强化颜色供用户来进行选择 这些强化色彩 看起来确实很惊艳 如果你要定制自己的 UI 元素 好吧 我先暂停下 大家先鼓掌 [ 掌声 ] 感谢强化颜色 所以 如果你要创建自己的 UI 元素的话 你需要自己创建一个主题 再把这些颜色融合进去 如果你之前这样操作过的话 你可能已经使用过 NSColor.currentControlTint 方法了 它会返回一个枚举结果 说明系统的模式是 aqua 还是 graphite 现在我们相比过去加入了更多的颜色 那个枚举结果自然就不够用了 因此在 macOS 10.14 我们请大家 切换到 NSColor 中的 controlAccentColor 这个方法

    NSColor 还能帮助你处理 强化颜色 NSColor 还能够帮你做很多其他的操作 如果你要创建一个 UI 元素 很常见的一个特征就是 你需要调整 UI 元素的颜色 来反映用户的互动 在这一点上 NSColor 引进了一种新的方式 就是 withSystemEffect 我们也预先定义了一些 关于互动的系统效果 例如按压状态 和停用状态 我们需要继续进行操作 给底色加上一个 适合现在外观的颜色 以及现在 操作面板中的互动元素 这样的话 能节省你很多的功夫 你不需要再 为这些状态开发一个配方 来进行颜色的调整 尤其是你需要 针对不同的互动 来适配数量超级多的 硬编译的颜色 大家都可以试试这个绝妙的 API

    我们来继续聊一聊颜色 macOS 10.14 有一个新的 功能特性 我们称其为内容着色

    大家看一下我这里的模拟 App 可以看到 这个 App 绝大部分都是用户内容 大部分都是文本 有几个元素 是我希望大家能够格外注意的

    这些就是用户可以 点击 然后开展更多操作的元素 在过去 我们不想使用 常规的按钮图形 因为我们觉得这样可能会冲淡内容的地位 但是在 macOS 10.14 中 我们可以允许你给无边框的按钮 着色 然后给调用 这些图像出现时着色 这样用户就能辨别出 哪些是可以点击可以进行互动的了

    这就变得很容易了 NSButton 和 NSImageView 这两个 都有一个新的属性 叫做 contentTintColor 你可以把它设置成任何想要的颜色 比如我之前提到过的 那些动态颜色 就是很好的选择 你也能够在 Interface Builder 里面进行设置 对于配置按钮来说 UI 外观大致就是这样的 对于配置图片试图而言 也基本是这样的 配色选项在这里 右边的工具栏中 我们已经讲了很多 macOS 10.14 中 关于外观的很多很棒的特性 我们也有更多的会议 大家在 WWDC App 里可以看到 我们最新的讲解 都是很不错的 接下来 我来讲讲下一个话题

    我们要讲 Cocoa 就必须要谈谈 layer backing

    我希望大家都能记住 在 macOS 10.14 中 当你要和新 SDK 连接时 AppKit 再也不会调用 打开窗口的后备存储器 而是直接提供 内容到窗口的服务器 它们使用核心动画图层 可能比较熟悉 iOS 开发的大家都会觉得 这个听起来似曾相识 但是大家还是 仔细看看这到底有什么不同 比如我们在 UIKit 有一个这样的树形视图 图像和图层的 关系其实是很简单的 每个图像都有一个图层 而且 图像间的父/子 关系也会 体现在图层树形视图中

    但是在 AppKit 中 我们创建的 图层树状视图 其实只是一个过程 只是处理视图层次的一个 附带产物 这样的话 我们就可以 在一些情况下 使用一个图层来处理多个视图 这一点很棒 因为这样可以减少系统内存消耗 GPU 内存消耗 也能减少窗口服务器 在显示屏幕时 要处理的请求压力 这里我也想要 特别指出 刚才我提到的这个特性是动态的 基于视图层次配置的 所以 它可以进行实时变化 因此 现在你就不能在图像间 图层间一直使用一种固定的父/子关系 这和过去的 iOS 是不一样的

    从编程角度来看 现在你不需要

    来使用图层了 当你在 macOS 10.14 操作时 AppKit 可以帮你搞定这些 如果你要配置 [ 掌声 ] 事实上 我们并不鼓励 大家使用这个属性 如果你把它设置成 ture 我们就必须保证每个图像都 能有自己的图层 这样的话我们就没办法开展想要的优化 开展想要的优化 也就是把多个图像放在 一个图层中 如果你要配置 旧版的 OS 的话 你可能还要用到这些 但是大部分情况下 你可以直接忽略它 不会有什么问题 我也想要谈谈大家 在 NSView UI 中 使用 CALayers 创建的其他样式 最简单的创建 CALayer 的方式 就是在 CALayer 类中 重写这个创建方式 或者调用一个委托方法 这个行得通 NSView 会给你提供很多功能 你不需要每一步 再耗费自己的精力去做 如果你调用 NSView 的创建方法 它就会自动运行 搞定很多事情 保证外观能够很好地 适配动态颜色 也会帮你管理好后备存储器的分辨率 而且 这个和 执行图层方法是一样简便的 所以 我建议大家能够在 图像层面来进行重写 而不是在图层层面进行

    在一些情况下 当你在执行 CALayer 的显示模式时 你正在直接更新图层的属性 这样做可能使你觉得更加高效 或者是这样做 能够帮你更好地 实现自己的构想 你仍然可以使用 NSView API 只要使用代理更新图层方法即可 这个和使用 NSView drawRect 方法 得到的效果是一样的 另外 你也可以 在 NSView 中 同步执行图层更新和调用绘画方法 如果你这样操作 当你的图像只有一个图层的话 我们就会使用 可选图层版本 如果你的图像正在和其它合并 以节省内存的话 我们就会使用 drawRect 版本 对于 printing 而言 我们也应用了这一点 所以 执行这两点是完全行得通的 如果你的一个图像 是使用 CG drawing API 无法实现的 AppKit drawing API 也无法实现 你需要做的就是 除了要使用更新图层方法外 还要调用代理 wantsUpdateLayer 方法 如果你返回 ture 的话 我们就能够知道你需要一个 显式图层来实现你想要的展示

    另一个能够将 AppKit 和其它核心动画特性发挥到极致 的方法是 使用 NSViews 中特别简单的 词汇创建 你自己的 UI NSImageView NSBox 以及 NSTextField 都是特别好的 创建模块 可以用来创建复杂的 UI 不论你使用何种技术来展示 它们都能适配正确的方式

    另外 因为我们对 layer backing 做了一些改动 有一些图案是 不再和 macOS 10.14 适配的 例如你使用 NSView lockFocus 和 unlockFocus 或者试图直接使用窗口的图像内容 实际上有更好的实现方式 你只需要子类 NSView 并执行 drawRect 就行 这些方法之前都有些繁琐 所以 你其实能够省去一些麻烦 其次 我还想要说一点 这个其实是用 Objective-C 写的 似乎在关于 Swift 的演讲中出现 有些奇怪 事实上 最好的消息是 我还真没有看到 任何 Swift 代码使用这些 从中我觉得 我不希望你们 做第一个尝试并给我惊喜的人

    最后有关我们对 layer backing 做的改动 还需要再说一点 如果你使用 NSOpenGL 类 来和 OpenGL 进行协同操作 要和 macOS 10.14 连接的话 我们一些执行细节 有关我们将图层关联 OpenGL 系统 的执行细节这一层面上有一些不同之处 大家也可能发现了一些小小的变化 不过最重要的是 我想要大家明白一点 在 macOS 10.14 上 我们不推荐大家 使用 OpenGL 如果你过去一直使用 NSOpenGL 我们真的建议你换成 MTKView 今天我们还有一场会议 会仔细给大家介绍 如何帮助开发者为 OpenGL 采用 Metal

    还有最后一点我想要聊聊的变化 这个变化就是我们对于 字体反混淆化做的努力 大家可以仔细看看这两个屏幕的对比 左边的是 10.13 右边的是 macOS 10.14 如果我们看窗口里的文字的话 基本上是一样的 但是如果我们放大拉近 放大到 48X 的话 我们就能够看到 macOS 10.13 实际上用的是 色彩边纹效果来显示其字体 而在 macOS 10.14 中 我们不再用这个效果了 这就意味着 我们的文字在更广的平台技术上 会变得更加美观 当然在扩展缩放模式上也会更好看

    这样说来 我们还有很多好消息要和大家分享 有关这一点 我想要邀请 Jesse 上台给大家讲一讲 [ 掌声 ] 谢谢 Chris 大家好 今天很高兴能在这里见到你们 我有很多话题要讲 首先 我要从用户通知的框架开始 这个功能已经在 iOS 上 使用一段时间了 这次 macOS Mojave 我们将把这个功能 带给 Mac

    这个功能也能使用户更好地 控制通知 而且这还意味着 你的 App 也可以像在 iOS 上一样 与这些通知协同工作 它们将会使用 userNotificationCenter 的 NSApplication 方法 registerForRemoteNotifications 以及 requestAuthorization 方法

    作为工作的一部分 我们也会弃用一些已经存在的 用户通知相关的 API 尤其是在 NSApplication 我们将弃用 remoteNotificationType OptionSet 和 registerForRemoteNotifications 方法 以及 enabledRemoteNotificationTypes 性能 我们也会弃用所有的 NSUserNotification

    那么既然你要使用 SDK 重新建立 你最好升级用户通知框架

    接下来 我想讲一讲 NSToolbar

    当你想在工具栏中居中 一个项目时 你可能会想要在 item 的两个 你可能会想要在项目的两侧 各留一个灵活的空间 这种方式可以奏效 但还是有一些缺点 尤其是当你在工具栏中添加 额外的项目时 它将会 把你的项目从中间移走 所以 NSToolbar 现在出现了一个 新的属性 centeredItemIdentifier 你可以将想置于中心的项目设置标识 这样 NSToolbar 就会 一直将它放在那里 除非其他工具栏项目 迫使它移动 否则它会一直在那里

    这里还有另外一个改变 也值得一提 就是自动布局现已用于 衡量工具栏的项目 在最大或最小的尺寸 没有进行规定的时候

    这个功能仅适用于 10.14 SDK 的 App 但是这意味着比如说你可以 比如说你可以改动 按钮的大小 测量功能将会替你完成的 [ 掌声 ] centeredItemIdentifier 行为在 Interface Builder 中 也可使用 这是工具栏项目的 检查窗格 你可以看到在最底下 有一个新的勾选框 写着 “Is Centered Item.” 你可以勾选上 而不必再在代码中 进行设置 而且也不必再退回编程 API 你可以继续在 Interface Builder 中 进行你所有的 UI 工作

    提到 Interface Builder 我简直产生了无法形容的激动 因为 Interface Builder 新增了支持编辑 NSGridViews

    如果你对 gridView 不熟悉的话 我可以告诉你 我们多年以前就引入了它 它是一种早期的布局 使用一种方格状的结构 来呈现你的视觉效果 这是从一个钥匙串访问 App 中取的范例 你可以想象 要是手动创建这种布局 要动用多少系统规定参数 你还可以使用 stackViews 来构建这种效果 但是 NSGridView 使整个事件更加容易 并且这个 Interface Builder 中全新的编辑功能支持简直太赞了 太赞了 让我来给你展示一下

    这是一些 UI 来自 storyboard 文件 你可以选中这些控制量 然后将它们纳入到方格的试图 那么之后 你就可以进行操作 将这些小格子的 填充和直线 调整成你想要的样子

    编辑 UI 的工作方式很像 编号电子表格 App 你可以将视图拖拉或者放置到 cell 里 你可以成行成列地选中 并调整它们的属性 你甚至可以合并 cells 正如你看到的最后两行那里

    这里举个例子 我们选中一列 这就是检查 窗格显示的样子 可以看到 你能调整 这一列 cells 的位置 你可以调整头和尾的填充 如果我们切换到尺寸检查器 你可以给纵列调整 00:32:41.336 --> 00:32:42.976 A:middle 明确的宽度

    如果你不进行设置 纵列的大小就会 根据内容自动调整

    关于这个特性 另外一个特别赞的事情就是 它是可逆展开 GridViews 在 Interface Builder 中可使用 同样也可以回用到 macOS 10.13.4 如果你还没有使用合并的 cells 你甚至可以回用到10.12 所以 如果你想要将你的 App 使用在较老版本的 macOS 上 别再等待了 直接使用这个超赞的新功能吧

    下一个我想要聊的话题是 NSTextView 的一些改变

    首先 有一些新的代理方法 第一个是 fieldEditor 配置了一个 textView 为了给 NSTextField 用作 fieldEditor 这些都提供了一个更为简单的方式 来配置 textViews 用于常见案例的使用

    后面的三个使得 textViews 被纳入到 scrollViews 这是目前为止 textView 最为常见的 使用案例 但如果你不得不对 textView 做 额外的配置 一定要记得查看 scrollView 的 documentView 这非常重要

    这些在 Interface Builder 同样也是 可以使用的 因此 再次重复 这里也没有必要去 后退回编程 API 下面让我们看一下 它们是什么样子的 这里的窗口做例子 显示了全部的 4 个 TextViews 有时候 会被误配置 当客户需要在 textField 中优先 fieldEditor 时 所以 使用一个 fieldEditor 代理方法可以帮助避免此问题 下一个 scrollableTextView 应该被用于 textViews 中弹窗和检查器窗格的 补充文本 诸如此类的情况 接下来 最下面的两个 适用于文件内容的文本 左边的适用于格式化文本 右边的适用于纯文本 在这一点上你可能会想知道 它们的区别是什么 因为看起来真的非常相似 主要的好处就是 你不必再担心 系统配置的问题了 比如说 黑暗模式的系统中 它们会看起来截然不同 格式化文本的 textView 仍保持 白色背景 而纯文本会变成黑色 来匹配剩余的系统 所以 通常来讲 如果你使用这些 代理方法 会帮助你维持 你的 App 与系统其它 App 保持一致

    我想说的关于 textView 的另一改变是 修改文本的新方法 PerformValidatedReplacement 这个方法背后的想法是 它提供给你一种非常简单的方式 去修改 textView 中的文本 而且还给你一种行为 就像是用户自己 做出了这个修改

    它控制了所有 适合的你期待的方法 但是 真正有趣的部分是 任何一个属性 当它没有被特定指派给 输入的字符串时 textView 的 typingAttributes 会自动将其 匹配输入

    我来给你们举个例子吧 这个窗口有一些格式化文本 代码中的一个小片段调用 performValidatedReplacement 去在中间插入 "Developers" 这个单词

    如果我们运行这个 这就是我们 获得的内容 单词出现了 而且与周围文本的 格式一致 我们不必去特别指定 任何一个属性 但是 这里也有一个细微的地方 需要注意 因为后退 属性来自于 typingAttributes 因此 如果你开始使用格式化文本来进行 此操作 插入的部分 最后就会显示为亮色 我们运行的还是同样的代码 这就是结果 格式属性 来自于最后的亮色部分

    这个原因让你发现 在调用 performValidatedReplacement 之前 你需要为你即将取代的部分设置 设置选定的范围

    如果你如此操作的话 这就是你获得的结果

    对于下一个话题 连续相机 我想快速讲一下 这是在 macOS Mojave 中另一个很赞的特性 如果你只是使用 标准的框架类 比如 NSTextView 要利用这个特性 你不需要做什么 特殊的设置 框架会为你解决一切事情 但是 如果你有更多 特定的 App 需要用到它 你可能需要更直接地使用它 另外还很重要的一点 需要了解的就是它是使用 现存服务的 API 去执行的 所以 你需要做的就是告诉 一个框架你的回应 类有能力解决图片数据 并且 你可以通过执行 validRequestor 来实现 如果你想尝试 我会鼓励你去查看 validRequestor 的文稿以及 其他一些相关的方法

    下面我想讲一下 自定义快捷操作 昨天年度咨文部分的会议上 你可能听到一些关于 快捷操作的内容 快捷操作使得简单的操作动作变得非常容易 比如说打开一个最喜爱的 App 复杂的动作比如 筛选文件或者调用脚本 也很简单 你可以使用 App 扩展或者 Automator 的动作套装 构建自动移快捷操作 它们在很多地方都非常有用 并且也有诸多方式 可以调用它们 但是 到目前为止我最爱的还是触控栏 如果将你的快速操作应用到 触控栏上 会非常容易就可以使用 不管你在哪儿 不管何时你需要它们 你可以通过键盘的偏好设置中 偏好设置中获得 这项操作 并且可以重新设置你的触控栏 是一直展示 还是当控制功能键的时候 进行折叠 或者 你可以将触控栏自定义 将工作流的按钮 拉进控制脚本中

    还有一点值得注意的是 你可以去快捷窗格浏览 在服务下面查看 这里你可以通过打开或者关闭 来控制哪一个 可以显示出来 正如我提到的 它们不仅仅是显示在触控栏 我用访达窗格来进行举例 如你所见 contextual 菜单下面的 还有一个快捷操作 访达的预览窗格 也有很多快捷操作 显示在底部 而且完整的列表 在“更多”按钮下面 Automator 的行动套装显示在 服务菜单里面 比如说 TrimLogs 就是一个我写来用于 筛选校正错误的日志的

    这也引入了我想要说的 下一个话题 创建行动套装 也被成为 contextual 工作流 这是 Automator 的新功能 当你进入 创建一个新文档 会有一个关于 contextual 工作流 的新的可选项 他们看起来很像平常的工作流 除了在顶部有一个新的块 可以让你 配置输入和 输出以及选择图标和颜色

    我们来迅速浏览一个示例 我经常会面临一个问题 当我想在 TextEdit 中打开一些文件时 我打不开因为 没有文件扩展 使用 Automator 就会非常容易就解决

    你要做的只是点进资料库 将打开访达项目行动 拉取出来 你可以将其配置成为用 TextEdit 打开 不再使用默认的 App 在访达中被选中的文件 自动成为这个动作的输入内容 如果你用什么名字保存这个文件 就会 自动出现在触控栏中 或者在其他有用的文本下

    总结来说 我们提到了 许多新的功能 以及其他的一些改变 将会使你的开发经历更为丰富 你的 App 更加伟大 查看新的 SDK 并开始在你的 App 中 使用这些内容

    会让你的 App 吸引人 你的顾客也会喜欢 更多信息 可以查看以下 URL 并且 也可进入 WWDC 的 App 此演讲部分下查看 所有相关的演讲链接 都在这里 非常感谢 [ 掌声 ]

Developer Footer

  • 视频
  • WWDC18
  • macOS 版 Cocoa 新功能
  • 打开菜单 关闭菜单
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    打开菜单 关闭菜单
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    打开菜单 关闭菜单
    • 辅助功能
    • 配件
    • Apple 智能
    • App 扩展
    • App Store
    • 音频与视频 (英文)
    • 增强现实
    • 设计
    • 分发
    • 教育
    • 字体 (英文)
    • 游戏
    • 健康与健身
    • App 内购买项目
    • 本地化
    • 地图与位置
    • 机器学习与 AI
    • 开源资源 (英文)
    • 安全性
    • Safari 浏览器与网页 (英文)
    打开菜单 关闭菜单
    • 完整文档 (英文)
    • 部分主题文档 (简体中文)
    • 教程
    • 下载
    • 论坛 (英文)
    • 视频
    打开菜单 关闭菜单
    • 支持文档
    • 联系我们
    • 错误报告
    • 系统状态 (英文)
    打开菜单 关闭菜单
    • Apple 开发者
    • App Store Connect
    • 证书、标识符和描述文件 (英文)
    • 反馈助理
    打开菜单 关闭菜单
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program (英文)
    • Mini Apps Partner Program
    • News Partner Program (英文)
    • Video Partner Program (英文)
    • 安全赏金计划 (英文)
    • Security Research Device Program (英文)
    打开菜单 关闭菜单
    • 与 Apple 会面交流
    • Apple Developer Center
    • App Store 大奖 (英文)
    • Apple 设计大奖
    • Apple Developer Academies (英文)
    • WWDC
    阅读最近新闻。
    获取 Apple Developer App。
    版权所有 © 2026 Apple Inc. 保留所有权利。
    使用条款 隐私政策 协议和准则