大多数浏览器和
Developer App 均支持流媒体播放。
-
字体管理和文字缩放
自 iOS 13 起,您的 iOS app 可以为整个系统提供字体。了解如何在 iOS 上管理字体,以及如何安装和访问字体。详细了解供用户选择字体的字体选择器界面,以及现可在您的 app 中使用的系统 UI 字体。了解不受设备限制的文字缩放最佳做法。
资源
相关视频
WWDC20
WWDC19
-
下载
(字体管理和文本大小)
早上好 我是 Julio Gonzalez 我是键入工程团队的主管 今天很高兴能来这里与大家分享 我们在iOS中 对文本和字体所做的新改进
我们今天的议程很满 一开始我要讲用于你app中的一些 新的系统字体
然后接着讲如何创建app 使字体在全系统内可用 以及如何使app访问那些 非常相同的字体
然后我们讲app选择字体的新机制
最后讲一些文本缩放注意事项 你可能会在把你的iPad app 引入Mac时遇到这种情况
让我们开始讲吧 我们在所有新版本中 提供三种新的系统字体 第一种是一种圆角系统字体 你可以在这里看到 Reminders app最顶部 Scheduled标签上有使用
还有一种衬线系统字体 你可以在这里看到它在 Books app中有多处使用
最后还有一种单间距系统字体 你之前可能在Swift Playground中 看到有使用 我鼓励你参考 Human Interface Guidelines 了解如何在你的app UI中 最好地使用这些系统字体
你可以通过UIFontDescriptor中的 新API获取系统字体 我们为你定义了四个新常量 第一个也是默认常量 是标准系统无衬线系统字体 这些年来你们一直都在用 然后我们给每个新添加的系统字体 都定义了一个常量
你可以通过一个叫做withDesign的 新方法使用这些常量 这个新方法用于转换字体描述符 从一个设计转换到另一个设计 用起来很简单 从字体描述符开始 在这个例子中 我们从已经实例化的 粗体系统字体中 得到了一个字体描述符 然后我们要做的就是 获取圆角系统字体 我们用圆角常量 调用withDesign 如果成功 我们就可以实例化 我们的圆角粗体系统字体 请注意 我们使用了高层级的API 实例化系统字体 我们没有通过使用它的名称 来实例化系统字体 那是我们的下一个话题
我们已经注意到许多app 至今仍然按名称实例化系统字体 我们以前强烈反对你们这样做 那么从新版本开始 任何诸如此类的字体实例化 均会导致失败 你需要使用高层级的系统调用 来实例化此种字体 你知道你正在按名称实例化系统字体 因为如果你看一下你传给它的名称 如果它以点为开端 那你就正在使用 一个Apple私有名称 现在按名称实例化字体 有许多很好的理由 这是你如何在app中 访问自定义系统字体的方式 以及如果你解析文档 这就是你如何 实例化文档所需要的字体的方式 现在我们还注意到许多app 没有恰当地处理 按名称进行的字体实例化
有时候它们会发生崩溃 原因就是 因为他们实际上并没有查看 实例化所返回的结果 他们假定实例化总是会成功 因为我们修改了OS中的某些字体 或我们从OS中移除了某些字体 那些 那些字体已不存在了 因此 你不能假定 不存在于OS某版本上的字体 会在另一个版本上存在 你需要注意实例化的结果 并在app中采取适当的行动 如果必要的话用另一种字体替代
那么我想把主题切换到我作为用户 和作为字体开发人员 已经期待很久的一些功能上 即app可以在OS系统范围内 安装字体的能力
我们把这些app叫做 字体提供器app 从根本上说 它们是你提交到Store中的 可以让字体在OS系统范围内 可用的app 与那些app一起 我们还创建了 非常简单的UI设置 在这些UI设置中用户可以浏览 app所安装的字体 以及移除他们不再想使用的字体
要创建一个这样的app 需要满足两个条件 第一 app必须包含 entitlement 第二 当app被提交到 Store时 它需要同时提交 app提供给OS的所有字体 这很重要 字体必须是app捆绑包的一部分 或是资产目录的一部分 关键点在于OS 不会允许字体提供器app 安装任何任意的字体 因为你把字体提交到 Store用于验证 它的验证流程类似于 我们在macOS中的 Font Book验证流程 我们要做的其中一件事是 检查字体的格式的类型 我们支持全部现代格式 ttf、 otf、ttc及它所有的现代变体 我们不支持旧字体格式 比如suitcase字体 或postscript字体
获取entitlement 非常简单 在Xcode中有一个新功能 叫做Fonts 一旦你选择它 你将面临两个选项
第一个选项是安装字体 那会使app在全系统范围内 提供字体 第二个选项是使用已安装的字体 我们为什么需要这个选项? 嗯 默认情况下app不能访问 用户已安装的字体 app需要通过选择 这个功能选择加入 从而可以查看那些已安装的字体
现在这些app的客户或用户 将有一些期待 第一个就是 app应该提供一个有意义的UI 用户可以浏览安装的字体 并移除字体 这很有必要 因为在iOS中 OS中没有像macOS中那样的 能安装字体的app
同时app应该响应系统字体 变更通知 原因是 用户能从设置app中移除字体 app应该注意用户何时移除了字体 并更新它的UI 最后如果你有字体提供器app 并计划为用户提供一大套字体 一大套字体库 我们强烈推荐你使用按需资源 并把字体打包到一个资产目录中 这是提交用户所需字体的一种 有效得多的方法 因为用户只能下载 他们实际上要使用的字体 而不是下载一个巨大的字体库 因为他们只使用少量字体
让我们去演示机器那给你们演示 这个功能是如何运作的
假设用户已经从Store下载了 一个浏览文档的app 这就是一个浏览文档的app 我把它叫做Font Consumer app 在左侧 它有一些能显示的文档 在右侧 它仅显示文档内容 让我们继续并重新加载这个文档 请注意表单出来了 这张表单并不是由app打开的 而是由OS打开的 之所以这样是因为它注意到 这个app正在尝试访问三种字体 而这三种字体在这个app上不可用 因此这个app替换了字体 以Helvetica字体 显示文档内容 那么用户所要做的就是 尝试找到一个 能在OS上使用那些字体的app 假如他们已经从Store中 下载了一个这样的app 我把它叫做Font Provider app 在左侧 它有一套我可以使用的字体 在右侧 它显示了字体的简单的预览 让我们继续并注册所有字体 请再次注意 这个表单出来了 它不是由app打开的 它是由OS打开的 这很有必要 因为在OS中我们不允许 app以用户名义悄悄地安装字体 必须经过用户准许 这也就是这个对话框的功能 那么让我们继续并准许
请注意UI 所有字体名称从红色变成了黑色 app以这种简单的方式来表明 字体已经注册成功 让我们确保它们已经注册成功了 我现在可以进入设置app 然后General、Fonts 在这里有一个新设置 有字体提供器app所提供的 全部字体的列表 我们看到了Font Provider app所提供的字体 我可以浏览其中一种字体 Century Schoolbook 你可以在这里查看 不同字体的预览效果 我现在就要尝试移除这个字体
我要继续并移除它 我要移除Century Schoolbook 现在它已经从列表中去掉了 现在我希望我的app 能注意到字体已被移除 确实 它现在以红色显示那种字体了 因为它监听了字体变更通知 并更新了UI 我们继续并注册所有字体
我要返回到Font Consumer app 我现在看到文档已经不再 以Helvetica字体显示了 它实际上也监听了字体变更通知 请注意所有字体现在都可用了 如果我查看其它文档 我看到它们 没有使用Helvetica字体 它们用Font Provider app所提供的不同字体
现在让我在代码中给你演示 如何创建一个这样的app
在CoreText中 特别是在 CTFontManager.h中 我们引入了一套全新的API 所有新引入的API 都在那个页眉文件中有记录 注册字体有三种新方式 其中一种是通过使用 指向字体文件的FontURLs 还有一种方式是你可以通过使用 FontDescriptors注册字体 最后一种是你可以注册 存在于资产目录中的字体 如果你有一大套字体库 你可以采用第三种方式 你可以创建一个资产目录 并且你可以使用按需资源 向用户提交字体 请注意最后一个API在你的种子中 不可用 但它在下一个即将到来的种子中可用
还有一个新API Font Provider app 可用于访问已注册的字体
最后一个API 是任何app都能用于 查看用户安装了哪些字体 你可以通过选择 我之前给你展示过的使用字体的 entitlement来访问这个API 那么让我们看看这些API是如何 在两个演示app中使用的 让我们从Font Provider app开始看 它是个很简单的app 只有大约20种字体 你基本可以按家族注册字体 那么我们要做的就是 收集所有字体文件 以及指向它们的URL 一旦我们准备好了 我们可以调用注册API 然后必要时更新UI 让我们从查看更新UI的代码开始
请注意Font Consumer app 和Font Provider app 都利用了字体通知来更新UI 当我们在这个演示中注册字体时 我们要使用同样的技巧 要监听这样一条通知非常简单
我们告诉通知服务中心 观察KCTFontManager注册 注册数量很少 RegisterFontsChanged通知
一旦我们在选择器中 得到这样一条通知 我们要做的就是更新已注册的字体 我马上会给你展示相应的代码 然后我们更新我们的UI 就像你在 Font Provider app中所看到的那样 从根本上说 对于已经注册的字体家族 以黑色显示名称 而对于未注册的字体则以红色显示
要注册字体 我们需要收集代表我们想要注册的 字体家族的字体文件 并调用我们的新API CTFontManagerRegister FontURLs 我们传递一个字体URL列表 以及一个范围 一个叫做Persistent的 注册范围 这是iOS 13中的新功能 它表明了字体在系统范围内可用 同时在这个例子中 布尔型标志 表示我们希望所有字体在OS上可见 API获取一个闭包 它需要闭包的原因是 它是个异步API 当你注册字体时 如果发现报错的话 将多次调用你的闭包 这可能是其中一个例子 当整个操作完成后 闭包中的完成参数就被设为真 对于这个演示来说 我在闭包中 要做的唯一一件事就是查找报错 我只需要登录进去 我不更新我的UI 当我更新时 我使用 我依赖于通知机制 来更新我的UI 一旦我收到通知 我就调用这个方法 我会直接调用新API CTFontManagerCopyRegister FontDescriptors 从而了解我的app 提供哪些可用字体 一旦我得到了这个信息 接下来就简单了 我只需记录字体描述符列表 更新我的家族模型 并从那里更新我的UI 这个Font Consuming app 它是个非常简单的app 功能就是解析文档 这种解析文档的app的关键在于 随着整个文档的解析 你要找出哪些字体可以被实例化 并保留一份列表 实际上缺少一个字体流动列表 可能会由于用户从未安装过字体 或进程中尚不能使用该字体 而导致字体缺失 你实际上需要利用新API 从OS中请求那些字体 一旦拥有了字体 你就可以更新UI 或更新文档了 对于一个解析文档的app来说 JSON是一种非常简单的 富文本文档压缩格式 它的功能是在每次运行时 都尝试实例化一种字体 如果它不能实现 它会用Helvetica字体替代 但当它替代那种字体时 它保留一份它不能执行实例化的 所有字体名称的流动标签 通过这些 现在我可以创建 使用那些名称的一个列表 或一组字体描述符 并把那个数组传给 CTFontManagerRequestFont 这个API的功能是注意或查看 用户是否使用Font Provider app安装字体 如果是 它会让字体 在app上可实例化 如果有字体不能进行实例化 那些字体将使用你之前看到过的 缺失字体对话框显示
API获取一个闭包 对于这个app来说 对于可见文档 我们只使用任意可用字体 更新所有缺失的字体 那么如你所见 对于app来说 利用其它app提供的字体 非常直截了当
现在我要与你们分享一些注意事项 对于字体提供器app来说非常重要
首先字体提供器app不能操作 不属于它的字体 比如它不能尝试注销 其它字体提供器app已注册的字体 类似地 字体提供器app不能覆盖 其它字体提供器 app使其可用的字体 或已安装在系统中的字体
OS有关于可以注册 多少种字体的限制 并没有固定的数量限制 从根本上说 取决于由不同的字体提供器 所安装的字体类型 每种字体都可以使用不同数量的资源
以这种方式安装的字体 不参与字体后找 从根本上说 它的意思是如果系统确定 你的字体是显示指定字体的唯一方法 它将不会自动替换并使用 实质上唯一方法是指 如果字体按名称引用 而使用这些字体的唯一方法
最后字体提供器app 拥有它们所安装的字体 意思是如果用户删除 安装有字体的app 那些字体也会被移除 系统确实会警告用户 表明他们正在尝试删除 已安装字体的app 用户有机会退回 这就是我要讲的全部内容 但在我离开之前 我想与你们分享 下面这个功能 我们对此感到非常激动 在OS中安装各种各样字体 并且所有app都可以在某个时间点 使用它们 这对于创建优质内容来说至关重要 通过这个功能 我们就可以在平台上解锁 创建优质内容的能力 特别是在iPad平台上 我要邀请 Eric Dudiak上台 他会为大家分享 关于在OS中选择字体的一些新技巧
大家好 谢谢Julio 我是Erik Dudiak UIKit团队的一名软件工程师 我们刚了解了 如何提供和安装自定义字体 但你的app可能还想使用那些字体 那么让我们看一下如何允许用户 选择并使用他们已安装的自定义字体
app要做的第一件事可能是 尝试在系统上枚举全部可用字体 并呈现给用户 然后允许用户选择其中一种字体 然而在系统上枚举全部字体 只能提供内置字体的列表 它不能显示任何自定义字体 因为这没有考虑到隐私权 所以是不允许显示自定义字体的
那么相反 当你的app想允许用户 选择他们已安装的其中一种字体时 我们在UIKit中提供了一个 新视图控制器 即UIFontPickerViewController
现在它可以以模态呈现 并默认显示 你在iOS 13中见过的新表单 或者如果是带检查器的 生产力app 你可能想把它嵌在侧边栏中 字体选择器也支持这个功能
那么让我们看一下 UIFontPickerViewController 为了安全起见 它完全在你的app进程之外运行
默认情况下 它还将只显示内置字体 你需用一个entitlement 来查看用户所安装的字体
用户从字体选择器中选择一种字体后 当前app中将可以使用这种字体 通过常规的字体API实现
然而 只有当用户选择它之后才可用 并且只有用户所选择的字体可用
因此 为了方便 所有不同种类的app 在UIFontPickerViewController上 有一些很棒的自定义选项
比如可能有app 想显示指定faces 现在默认情况下 字体选择器将只显示字体家族 这类似于比如Mail这样的app 并且许多用户也都熟悉这种方式 然而如果你有一个app 它有理由显示不同字体的额外比重 比如半粗体或中粗体 你可以有选择地在字体选择器中 进行配置
此外 你的app要选择 它是否获得 这里所显示的WYSIWYG呈现 或系统字体中所显示的 每种字体的更默认的呈现
现在 你的app可能还想筛选 对用户可用的字体列表 你有两种实现方式
第一种 你可以按特征筛选
如果你的app显示源代码 比如 你可能只想查看 或只想给用户显示单间距字体 因为那样对于查看源代码来说 会更自然 在这里我们看到 按特征筛选的筛选条件为仅单间距
此外 你的app可能需要让字体 支持特定语种 从而在它所使用的情境中能讲得通 为此我们提供一个 Filter Predicate API 允许你筛选字体所要支持的单一语种 或几个语种的组合 从而能呈现内容 在这个例子中 我们看到字体选择器配置为 仅显示支持汉语的字体
字体选择器还存在于macOS上 供UIKit app使用
如果你只呈现字体选择器 而不是我们之前看到过的那个 模态表单呈现 你将看到类似这样的东西 一个更传统的Mac菜单
为了控制 这个菜单在你的app中 所呈现的位置 因为它应该在用户刚点击过的按钮 上方显示 在视图控制器之外使用 UIPopoverPresentationController 来选择用于呈现它的视图
除此之外 使用菜单的语义学 基本类似于视图控制器
点击关闭菜单 比如说 与遣散视图控制器相同 当用户在菜单中 确实选择了一种字体时 它将自动发送委托API 就像视图控制器通常会做的那样 然后关闭菜单
这是在macOS上围绕字体选择 提供一种更传统的体验的方式 从而你的app感觉就像是 用户期待在常规Mac app上 所期待的app的样子
当然 macOS 有额外的字体选择选项 以一种macOS 字体面板的形式实现
运行在macOS上的 UIKit app支持这种形式 它甚至包含在菜单栏的默认选项内 因此 用户可以在任意时间 打开或关闭它 并在你的app运行的任意时间内 选择不同的字体设置
现在你还可以通过程序 控制字体面板的呈现 并且你可以通过 UITextFormattingCoordinator访问它 你可以在那查看当前是否显示面板 并手动打开或关闭它的呈现
由于字体面板的非模态本质 当你的app在macOS上运行时 有一些注意事项 来自字体面板的变更 将贯穿响应器链
当使用标准UIKit控制时 系统会替你自动处理它 通过UITextFormattingCoordinator 实现 事实上 共享的 UITextFormattingCoordinator 甚至可以被用作我们之前看到过的 字体选择器的委托 因此你还可以通过响应器链 为那些变更指明路线
然而 如果你的app中 有自定义UI响应器 你可能需要采用 一些新 UIResponderStandardEditActions 协议方法 以便当字体通过字体面板 发生变更时收到通知
这将允许你的自定义响应器 相应地更新它们的显示
现在让我们快速看一个演示 看这些是如何运作的
很棒 这是Font Consuming app 在这里我们看到 它已经使用了自定义字体 但这个app的一个很棒的功能是 它还让客户选择他们想看到的字体 而不仅仅是显示字体 我们可以随时修改文档字体 我只需要按这个修改标题按钮即可
我按下这个按钮时 我们看到我得到了字体选择器
我得到了一个 我最近用过的字体的列表 我还可以进行搜索并扫描 从而寻找我想要的那个字体
现在我们已经把它自定义为 显示额外的faces 因此我可以看到 指定字体的任意faces 我要扫描它并找到我想要的那种字体 让我们看一下 让我们使用Papyrus字体
太棒了 我可以像那样修改标题
并且你可以在任意app中 实现这个功能 提供很棒的标准控制 可以让用户在iOS上变得习惯
当然 当然 因为这是一款 iPad app 我们还可以把它引入到macOS上
在这里我们可以看到 这与我刚在iPadOS上展示的 那个app是同一个app 现在它运行在macOS上
现在因为我们没有太多地自定义 如何呈现标题菜单的字体选择器 如果我继续并按下同一个按钮 而不修改app的任何代码 我们可以看到它没有显示 当我在iPadOS上运行时 所看到的字体选择器ViewController 而是得到了一个菜单
在那个菜单中 我仍能得到许多 与iPadOS上运行字体选择器时 得到的功能相同的功能 我仍能在顶部看到Recents 并且我仍能选择单个face 我也仍能得到那个 WYSIWYG呈现 从而我能很好地了解我所选择的字体 到底看起来是什么样子 在这个例子中 我要继续并选择 Comic Sans
现在我们已经在app中实现了 当在macOS上运行时的一些 额外自定义 因为我们可以使用字体面板了 我们可以继续并更新这里的正文 从而响应 来自字体面板中的任意变更 我们实现这个功能之后 我们还可以让修改正文按钮 在macOS上运行时 不显示字体选择器 而是显示字体面板
这可以让我们做一些额外自定义 我可以像在字体选择器中所做的那样 修改字体 但在macOS上 我还可以在这里 做一些额外的格式修改 我可以修改 比如说文本大小 或甚至是文本颜色
这在macOS上提供了一种 非常丰富的体验 这种体验是多年以来用户所习惯的 Mac app的体验
太棒了 这是我们的示例app 让我们看一下 我们是如何在代码中实现的
首先让我们看一下 如何创建字体选择器 首先第一步是给它创建一个配置 在这个例子中 我们实例化配置对象 并告诉它当我们显示字体选择器时 我们想包含faces
设置好配置之后 我们现在可以创建字体选择器 并传入那个配置 配置将决定字体选择器 在它的整个生命周期中的行为
我们还把我们自己设为 字体选择器的委托 从而当用户选择字体时 我们得到所有的回调
最后我们只需要呈现字体选择器即可 就像我们呈现其它视图控制器一样
现在 在委托回调中 我们看到我们可以获得 用户直接从字体选择器中 所选择的字体 在这里我们看到当用户 确实选择了一种字体时的委托回调 在这个例子中 我们把用户所选择的字体 从字体选择器中取出来 并把它发送给你app中的一个 属性化字符串
当然 如果用户取消选择字体 我们也会收到通知 因此我们可以针对取消 做出恰当和必要的修改
最后让我们看一下自定义响应器代码 这是当在macOS上运行时 我们处理字体面板的方式 在这个例子中 我们实施了一个方法 它让我们了解用户何时更改了 我们应该使用的属性 我们不仅仅是获得 他们所修改的一组属性 我们实际上会得到这个便利的闭包 它包含我们当前所拥有的一组属性 并在用户做出修改之后 传出应该传出的一组属性 这么做的原因是 根据用户所做的修改 当前属性可能会保持相同 或可能发生改变 比如 如果当前设置了下划线 那么用户修改文本的前景颜色 不应该改变下划线效果 在这个例子中 conversionHandler会替我们实现
让我们快速回顾一下字体选择
当我们想要显示用户字体时 在iOS、iPadOS 甚至macOS上有一个新视图控制器 UIFontPickerViewController 而不是在系统上枚举所有的字体
此外 在macOS上运行 UIKit app时使用字体面板 其中涉及一些额外的注意事项 因为自定义响应器可能需要处理 属性变更 app运行时 随时可能会发生属性变更
标准文本视图将自动处理这个问题
现在我想邀请Donna上台来 她会讲Apple跨平台文本缩放
谢谢Eric
文本缩放是我们在iOS 13 和macOS Catalina中 引入的一个新概念 今天我们要讲如何使用这个新概念 来确保app中的文本尺寸 处处保持一致
现在作为iOS开发人员 你很可能非常熟悉人机界面指南 这是指南中的一个表 它显示了默认动态排版的文本尺寸 UIKit app中的大多数文本 都使用正文文本样式 也就是17点
在iPad上看起来是这样的 读起来很容易 对吗?
你再看看Mac上 同样是17点的文本 看起来有那么点不一样
当你把这两个并排放在一起时 你可以看到通过对比 Mac上的17点文本看起来大一些
那是因为在Mac上 我们更习惯于较小的默认文本尺寸 接近13点 就像这里显示的这些文本
但如果我们把同样的13点文本 放在iPad上看
它看起来很小 读起来很费劲 这种不一致已经存在很长时间了 我们选择17点作为iOS中 可视键入缩放的基础尺寸 从而使文本易读并易于在触摸屏幕上 进行交互
但随着技术的进步 跨平台用户体验变得越来越重要了 现在你可以把你的iPad app 引入到Mac中了 用户一定会注意到 文本尺寸的不同之处 当你在Mac上同时运行 iPad app和AppKit app时 当在app之间复制和粘贴文本时 以及当并排浏览文档时
我们要如何让文本尺寸 处处保持一致呢? 理想情况是 如果我们正在浏览 同样字体和尺寸的同一段文本 我们希望它看起来类似这样 可视缩放适合每个平台 这里其实有两种不同的可视缩放
一种是用于iOS 和iPadOS上的缩放 默认尺寸为17点 我们把它叫做iOS文本缩放
然后还有用于macOS和其它 非Apple平台上的缩放 默认尺寸接近于13点 我们把这个叫做标准文本缩放
我们希望你们作为开发人员 能了解这两种不同的文本缩放 并恰当地使用标准文本缩放 如果它能改善跨平台用户体验的话 现在让我们看一些例子
首先是Mac上的iPad app
因为UITextViews是选择 显示大量文本的控件 你最可能在这里注意到其中的差异 我们想为你提供一种简单的解决方式
因此在iOS 13中 我们向UITextView中添加了一个新属性 叫做usesStandardTextScaling 打开它时 UIKit将在文本视图内 自动调整文本的渲染 以匹配标准文本缩放
让我们返回到这里的文本 我们可以看到缩放看起来稍微 有点偏了 好的 让我们看一下打开 usesStandardTextScaling时会发生什么
啊 看起来好多了
使用这个新属性的确是一个 确保文本 以标准文本缩放显示的好方法
但请注意usesStandardTextScaling 默认情况下是关闭的 那是因为在文本视图上 使用自定义转换的代码 可能没有预见到当与这个属性 相结合时所产生的结果 因此如果你想使用标准文本缩放 请确保你给每个文本视图 都启用了这个功能
接下来我们讲复制粘贴的文本缩放
现在因为iOS使用独特的文本缩放 你可能注意到这个可视尺寸差异了 当在UIKit和AppKit app之间 复制和粘贴文本时 如果你曾用过通用剪贴板 你实际上可能早就注意到这个问题了
嗯 好消息是你现在实际上不需要 做任何事就能获得这个功能
从最新版OS开始 你可以免费使用 视觉效果一致的复制和粘贴功能
让我们看一下它是如何运作的 这是两个平台 左侧是iOS 右侧是macOS
在每个平台上 复制和粘贴都在系统的两个 不同层级之间移动文本 这里的小跑步者代表运行时层 而这些磁盘代表持久层
运行时层中文本视图中的文本 作为一个属性化的字符串 当你复制那段文本时 它从运行时层的文本视图中移出来 并进入持久层的粘贴板中 并且把它序列化为富文本格式或叫做 RTF格式 用于存储在粘贴板上
在最新版OS上 我们给属性化字符串API添加了 新行为 它会写RTF 因此当你从属性化字符串中 创建RTF时 它将添加表示它所使用的 文本缩放的元数据
现在当在iOS上复制文本时 文本会用那个元数据进行自动标记 这个表示它使用了iOS文本缩放
现在我们还在属性化字符串上 给RTF读取API 添加了另一个新行为 因此当你从RTF 创建归属性字符串时 系统将查找那个文本缩放元数据 如果需要 它会替你调整文本尺寸
返回到我们的原始文本中 我们在iOS上复制了那段文本 当我们把它粘贴到Mac上时 系统看到元数据表明 它正在使用iOS文本缩放 然后系统会在属性字符串中 调整文本尺寸 从而当文本在Mac上显示时 它看起来 与iOS中的原始文本尺寸相似
最终结果跟之前的这个例子 看起来非常像 但字体尺寸不一样
我们在iOS上复制的原始文本尺寸 是17点
而我们在Mac上粘贴的文本尺寸 是13点
两个平台上拥有不同的字体尺寸 对于复制和粘贴来说已经没问题了 因为字体尺寸信息是临时信息 它只存在于运行时层中 但RTF也是一种文档格式 这对于存储层的持久性来说 并不是个好方案
这是我们的最后一种情况 用于文档互换的文本缩放
我们在这里权衡特殊考虑 从而平衡跨平台视觉一致性的渴望
与在文档模型完整性的需要
为了让文本在不同平台上看起来一样 同时也在文档中保持同样的文本尺寸 我们所需要的其实就是浏览文档时 使用一种文本缩放 并在保存它时使用另一种文本缩放
我们有两种不同的实现方式 我们可以修改文档模型 并对浏览和保存使用不同的文本尺寸 或者我们可以通过修改渲染缩放 来修改文档视图 并在保存时保持相同的文本尺寸
我们实际上对RTF 实施了全部两种方法 因为这是我们内部常用的格式 我希望与你分享 我们为了实现这个功能 所采用的基本技巧 从而你可以采用其中一些技巧 在你自己的流程和文档格式中 创建文本缩放支持
我们所做的第一件事是 扩展我们的格式 从而用那个文本缩放元数据标记文档 文档解析器和浏览器需要这个信息 来理解文档正在使用哪种文本缩放
因为早已存在的文档 不会拥有这个元数据 我们还需要把它们迁移出来 从而让它们使用新格式 对于RTF 这个过程是自动发生的 当文档在最新版OS上保存时 会自动使用新格式
现在我们还需要确保 我们的文档拥有与之相匹配的 正确的文本缩放 这对于初始迁移来说尤其重要 因此 我们引入了一个新的 属性化字符串API 以新文档属性形式提供帮助
现在你可以使用文本缩放文档属性 在保存时设置文档中的元数据 使用属性化字符串编写API 比如来自范围的数据
如果需要 当你保存文档时 你还可以把文档转化为 特定的文本缩放格式 你可以通过 同时指定两个新文档属性实现
对于基于模型的方法 我们需要一种能控制当打开文档时 不同文本缩放格式之间的转换的方式 为此我们引入了更多的 属性化字符串API 还有用于目标和源文本缩放的 新的读取选项
并且你可以控制使用哪种文本缩放 通过在从RTF文档中 创建属性化字符串时 指定这些读取选项实现
最后对于基于视图的方法 我们推荐使用标准文本缩放 现在对于RTF文档 你可以通过结合新API实现 当你把RTF读取到一个 属性化字符串中时 你首先把目标文本缩放设置为标准
然后在文本视图上设置 usesStandardTextScaling 它会显示文档
哦 好的 我们今天讲了很多内容 现在作为一个提醒 这是你今天所了解到的内容 iOS app现在可以使字体 在系统范围内可用了 仅对非系统字体使用名称实例化 请记住 名称实例化并不保险
请使用按需资源向OS提交字体 请使用标准文本缩放 以获取最佳跨平台用户体验
请参加几个小时后的 文本和字体演讲 你可以了解与我们今天在这里 所讲的话题相关的更多内容 你还可以在iPad app 和Mac演讲上找到我们 并了解关于文本缩放的更多信息
我们真的非常期待你们用这些新功能 创建出什么样的体验 谢谢 祝你们享受余下的会议时光
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。