大多数浏览器和
Developer App 均支持流媒体播放。
-
利用 SwiftUI 构建自定视图
了解如何在 SwiftUI 中利用高级组合、布局、图形和动画来构建自定视图与控件。观看高性能动画控件的演示,看看它是如何通过代码逐步实现的。更深入地了解 SwiftUI 的布局系统。
资源
相关视频
WWDC22
WWDC20
WWDC19
-
下载
(在SwiftUI中创建自定义视 图 图形效果和布局)
大家好 很高兴再次在WWDC 与你们见面 我是Dave 如果你曾看过 关于SwiftUI的其它演讲 你就知道把app的 各个部分装配起来 并让app开始运行是多么简单 今天我和John要介绍如何实现 从创建功能性app 到拥有精美布局的app 漂亮的图形和一些很酷的动画
我们会介绍SwiftUI的 两个子系统 然后John会上台来 用这两个子系统创建自定义控制
让我们开始吧 从你着手使用SwiftUI开始 你就已经在体验 布局系统了 你在预览编辑器中的文本四周 看到的那个蓝框 是它的边界 布局就是在屏幕上 规定某个东西的边界
让我们用这个例子 看一下底层发生了什么
从技术上说 这里有三个视图 分别是视图等级底部的文本
你的内容视图 它总是拥有 与它的主体文本一样的边界
最后是根视图 在这个例子中是设备的尺寸 减去安全区域尺寸 那么如果你在手机顶部 看到了这样的东西 比如它不含在内
小技巧 你仍可在那个区中安排东西 通过使用这个修饰器 好的 但默认情况下 你处于安全区
我们总是把任意带有主体的 视图的顶层叫做中性布局 因此它的边界 是由它的主体的边界定义的 对它们的操作一样 因此你真的可以为了布局目的 把它们当作同一个视图 因此这里其实只有两个视图 布局过程有三个步骤
第一步 根视图提供文本、推荐尺寸 由那两个又大又宽的箭头表示 因为它是根视图 它提供的是整个安全区的尺寸
下一步 文本回应 嗯 它对你慷慨得多 但我真的 我只能做这么大 在SwiftUI中 不能给子视图 强制规定一个尺寸 而是由父视图来决定
现在根视图说了 好了 我需要把你放在哪 那么我要把你放在中间
那么就是这样 这是个简单的例子 但每个布局交互表现方式都一样 在父视图和子视图之间 并且整个布局的行为 从这些父-子视图交互中浮现出来
但我想强调一下第二步 因为它与你所熟悉的不一样 它对你非常重要
它意味着你的视图有尺寸调整行为
因为每个视图都控制自己的尺寸 它意味着当你创建视图时 你就要决定 如何以及何时重调它的尺寸 比如 这个视图是不可修正的 50乘10点 由于它的根视图中框架尺寸是固定的
而这个是可灵活调整的视图 但高度和宽度总会一样 因此它的长宽比总是一比一 因此尺寸被封装到了视图定义中
我们还看到它也适用于文本
那么在SwiftUI中 文本的边界从不会超出 它所显示的行的高度和宽度 我们稍后讲堆栈时再了解 它为什么这么重要
在布局中还有最后一步 对于获得漂亮的UI来说至关重要 在SwiftUI中 你真的不用担心这个问题 因为我们会替你处理 但值得了解一下SwiftUI 把你的视图圆角化为一个 最接近的像素 你不会得到像这样锯齿形的边 而是利落的、清晰的边 这只是每个好app 需要了解的许多细节之一 但SwiftUI会替你分担 以你的方式 是的!
从而你可以重点关注 让你的app变得更特别的东西
好的 现在我们了解了基础知识 让我们看看 是否可以把它变得更好
我要把示例中的文本 修改成一些随机文本 比如 我不知道 Avocado Toast?
你们饿了吗?
不饿?好的 让我试试让它变得更诱人 我要在这里添加漂亮的绿色背景 现在这个背景修饰器在背景视图中 包裹了文本视图 颜色视图作为第二子视图
现在绿色背景精准匹配文本的边界
第二个小技巧 把背景或边界颜色扔到视图上 是个非常有用的技巧 如果你想观察视图的边界 并且没有便利的预览画布的话
好的 现在我想在绿框内的文本四周 留出更多的空间 因此我要在那插入一些内边距
现在SwiftUI选择了许多 适合我们的平台、 动态类型尺寸和环境的内边距
当你不传递任何参数时 你会得到适应性内边距 与SwiftUI适应性地调整 选择器或按钮的方式一样 取决于它所处的情境
并且如果我们只想适应性地填充 左右内边距 嗯 我们也可以实现
适应性修饰器是调整布局的最佳方式 因为你避免了把代码复杂化 避免在开发早期 在一些细节上浪费时间 并避免硬编码常量 这可能会在其它地方不合时宜
但因为我们在这里控制着这些细节 假如有个规范 要求所有内边距都是十个点
好的 你可以明确地写出来
这个例子比Hello World 更有意思一点 让我们在这个例子中看看 布局过程是如何运作的
首先 根视图为背景视图提供了 它的整个尺寸 与吐司视图类似 背景视图是中性布局 因此它会把那个建议尺寸 传递给内边距视图
内边距视图知道它要给它子视图的 每个边都添加十个点的内边距 因此它给它的子视图文本视图 提供的要少得多
文本占据了它所需要的宽度 并把那个值返回给内边距视图
内边距视图就知道每一边都要 比它的子视图要大十个点 并且它把文本恰当地放到了 它的坐标空间中
现在我们说过背景视图是中性布局 因此它只需要向上报告那个尺寸即可 但在此之前 它把那个尺寸提供给 它的第二个子视图 颜色视图
颜色在布局时非常顺从 它们接受提供给它们的尺寸 因此尺寸的颜色与内边距视图的一样
最后背景视图把它的尺寸 报告给根视图 并且根视图会跟以前一样 让它居中显示 这就是整个过程
准备好看另一个例子了吗? 这个例子更简单 但它很重要
那么在这个例子中 视图的主题 只是一张固定的20乘20的图片
SwiftUI中 除非在资产目录 或代码中你把图片标记为尺寸可调 否则就是固定尺寸
现在我希望视图 整个视图变大为原来的1.5倍 让我们添加一个30乘30的 框架修饰器 就像这个一样
现在你可能注意到了 图片虽然确实很可口 它的尺寸没有发生改变
但不应该太惊讶 是吗? 我们说过它是固定尺寸
在它周围你会发现一个 30乘30的框架 那是视图主体的尺寸 因此我们定义的视图 实际上比我们之前添加的修饰器 要大50%
因此框架尺寸与图片尺寸不匹配 这是个矛盾吗?
实际上不是 这是布局系统正在做它应该做的事
认出框架不是SwiftUI中的 一个约束非常重要 它只是个视图 你可以把它看作是一个图片框架
它给它的子视图推荐固定尺寸 但和其它视图不同 子视图最终会选择自己的尺寸
从这层意义上来说 SwiftUI 布局比你熟悉的更灵活
好处是 在SwiftUI中没有欠约束的 或超出约束的系统 意味着你能表达的一切 都拥有一个定义良好的效果
那么完全没有什么不正确的布局 除非你不喜欢你所得到的结果
好的 现在我们了解了一些基础信息 让我们讨论一下强大的工具 堆栈
现在HStack和VStack 分别以行或列安排它们的子视图 我把这个列表网格和四个堆栈 放到一起 只需要几行代码就能实现
这是那个布局的代码
顶层是HStack有两个子视图 第一个是VStack约束星形评级
另一个子视图还是一个VStack 它的两个子视图左对齐
其中第一个子视图 又是另一个HStack 约束标题、有弹性的间隔器 和牛油果图片
好了 四个堆栈 让我们把它们重新放到一起
我希望你注意到 SwiftUI没有粗暴地 把堆栈的子视图都堆砌在一起 它在两个子视图之间留出了一些空间 因为适应性间隔生效了
你还会发现的邻近文本的 基线到基线的空间 与Apple的人性化界面指南 完全相匹配
而基线到边界的空间也一样 因为我们把这些规则加密到了 SwiftUI的布局系统中
这里的一般规则是最简单、 最简洁的代码 也可以产生漂亮的结果
但如果你需要控制 一如既往 SwiftUI会支持你 它有旋钮 你可以打开或关闭 以获得你想要的结果
哦 我几乎忘了 SwiftUI还替你处理另一件事 若你的app定位在一个从右到左的 书写系统中 比如阿拉伯语 并且你修改了系统语言
SwiftUI会替你调整水平坐标 因此你不需要重新编写布局
如果你一直在思考 我们为什么说 leading和trailing 而不是left和right 现在你了解了吧 这样你的布局 会自动国际化
好的 让我们具体看看堆栈布局
现在 我们目前所看到的 绝大多数视图 实际上都是子视图的直链 但堆栈很有意思 因为子视图必须平等竞争一个空间
在这个堆栈中 我们已经说过 文本不应该超过一行
意思是如果堆栈被要求适应 较少的空间
嗯 文本将被缩短以适应它
但让我们从父视图 提供了足够空间的情况开始看好吗?
首先堆栈要计算出内部空间需求 并从建议宽度中提取那个信息 以便为我们提供未分配的空间的尺寸 现在我们有三个子视图 我们不知道它们的尺寸
因此我们决定把空间平均分成三等份 然后我们提议把其中一份作为 最不灵活的子视图的尺寸
现在 我们说过图片是固定尺寸 对吗? 那它就是最不灵活的那个
那么图片占据了这么多空间 是它所要求的尺寸 我们把那个尺寸从未分配空间中扣除
并重复这个过程 好的 我们现在有两个 未规定尺寸的子视图 因此我们把余下的空间分成两份 并把其中一半提供给 没有尺寸的较不灵活的子视图 即Delicious
Delicious占了这么多空间 你看到它占的空间比提供给它的少 记住这一点
把它从未分配空间中扣除 给Avocado Toast 留下了这么多空间 你可以看到 空间充足
好的 最后一步
现在所有子视图都有尺寸了 堆栈通过之前的间隔 把它们排列起来
因为代码没有指定对齐方式 默认生效的是居中对齐 因此堆栈使用居中对齐 把所有子视图垂直地居中显示
最后堆栈选择自己的尺寸 从而可以完全封装子视图
现在如果你思考一下 你可能会想 为什么文本的边界不会超出 它们所显示的宽度
请看 如果Delicious 接受了提供给它的全部空间 减少为Avocado Toast 提供的空间从而会迫使它截短图片 尽管事实是一切都要合适 有足够的空间
实际上 相对于这里的两段文本 Avocado Toast 明显更重要 对吧? 它是主题 Delicious只是个附属 它可以做出牺牲
因此这并不是个好结果
但现在我想了一下 那意味着空间的大小 所提供的空间比理想空间小 我们之前见过的截短行为很可能 也不完全是我们希望得到的
如果提供这么窄的空间 我们宁愿保留主题完整 并截短附属物
好的 为此我们有另一个 强大的工具 我们把Avocado Toast 的布局优先级从默认的零 提高到一
因此当堆栈中的子视图 有不同的布局优先级时 堆栈获取未分配的空间 它给所有优先级较低的子视图 留出最小宽度 然后把其余空间分配给 优先级最高的子视图
在这个例子中只有一个是最高优先级 就是Avocado Toast
并且会给它提供全部可用空间 扣除图片宽度 和把Delicious缩减到 最小后保留的三个点
好的 通过最高级布局优先级 调整所有子视图的尺寸后 堆栈继续给下一个 布局优先级最高的子视图 分配余下的空间 如此反复
好的 我还要给你们展示最后一个 强大的工具
对齐 现在我知道你对于我们能底边对齐 这个堆栈并不惊讶
那样看起来很不错 对吧?
但请考虑一下 当我们把Delicious的字号 改小时会怎么样
嗯 我觉得还不错 但我知道什么? 我只是个app开发人员 我很确定我的UI设计师 Crusty会觉得它是个问题
是的 他会一直放大 并开始像这样选择详细信息
他会说 Bucky 首先你有 Delicious的基线 就在此 然后图片的底边在下边 然后Avocado Toast的 基线却在上边 没有一个对齐的 我是怎么教你的?
幸运的是我们可以 在SwiftUI中解决它了
基于文本的排列工具始终是对齐 比如上下对齐
如果我们以文本的基线对齐文本 它就灵巧地解决了这个问题
那图片怎么办呢? 请看 图片中没有文本 但每个对齐都有默认值 并且最后一行文本基线的默认值 正是视图的底边 那我就得到了 Crusty要求我实现的效果
哦 哦 再看一下 我非常确定我感觉很不好 我非常确定他会告诉我说 上边有一个可见的基线 距离底部还有87.4%的距离
通过告诉SwiftUI 如何给 图片计算最后一行文本基线来实现 按照它的其它对齐方式
很酷 对吗?
但我们还没有完全利用 对齐工具的功能 让我们返回到内嵌堆栈例子中
假如我们想对齐这些星星 和标题的中心位置 就像这样
现在请记住 讨论中的文本 嵌在视图等级的两个不同的分支中
那么 嗯 居中对齐 那个顶层HStack的子视图 并不会切割它 因为它是默认的 是的 那么我们已经快搞定了 你可以看到那些子视图已经对齐了 不 我们要的对齐方式 和居中对齐不一样 标记星星的中间位置 和标题的中间位置
我们需要定义自己的对齐方式 实际上就是如此简单 只需要六行代码就能实现 我们在垂直对齐上实施一个扩展
首先我们定义遵循对齐ID的枚举 有一个要求 告诉SwiftUI如何计算默认值
现在在这个例子中 我们选了什么其实不重要 因为默认值不会超出那些内部的堆栈 但我把这个默认定义为底部 从而你可以看到 它就像定义对齐指南修饰器一样 最后我们定义垂直对齐的静态实体 把枚举类型作为它的参数
现在我们可以用它来对齐堆栈
明确地把它设定到 星星和标题的中间位置
现在我们所设置的明确的对齐值 穿过了所嵌入的堆栈的两个层 允许外部的HStack 对齐那些内部的部分
那么这就是自定义对齐
一个强大的工具 帮助你取悦最挑剔的UI设计师 现在我要邀请 John Harper上台 讲讲SwiftUI中的图形效果 John
谢谢Dave 是的 我要讲 SwiftUI的一些图形功能 以及如何使用它们在app中 创建交互性控制
这是我们想要创建的效果的示例 你之前见过 但只是几个普通的控制 然后在中间有这个大戒指的图形 四周有渐变 底部是一个条形图 如果你想在app中实现这种效果 你必须深入到图形系统内部 也许是核心动画或核心图形
我们认为在SwiftUI中 我们有一个好方法可以实现这种效果 我们先看个小例子 但在我们做任何复杂的操作之前 我们需要先了解基础知识 如果我们想绘制一个红色圆圈 我们该如何做? 嗯 我们首先要创建一个 自定义视图类型 因为我们知道所有一切都是视图 然后我们要把像这样的东西放进去 在这里我们说 如果给我一个图形和颜色 我能填充 把那两种东西填充到一起 屏幕上有一个红色的圆圈了
但这里有个非常有意思的事 就是我们没有给它提供位置尺寸 那是因为我们依赖于布局系统来实现 就是Dave讲的那些 让布局系统替我们布局我们的视图 即使我们就在这个绘图模型中
那么图形会反应给布局系统 并产生视图 事实上 现在我们的绘图核心 如果你那样认为它们的话 实际上只是视图 然后那其实意味着 SwiftUI中一切都适用于绘图 因为SwiftUI中的 一切都是视图 因此你所看到的全部修饰器 关于布局和动画、滤镜效果的修饰器 一切的一切所适用的绘图方式 都与适用于视图的绘图方式相同 但类似地 我们添加了大量的 新自定义修饰器 专用于图形绘制 比如模糊和阴影 但因为绘制的图形只是个视图 它们都适用于常规视图 以及图形视图 因此 我们认为这种统一的常规控制 比如视图和图形 会随着我们的进步变得非常强大
好的 但让我们具体看一下 基础模型是有一个形状和一个样式、 一种颜色或其它要素 其中两者的结合产生一个视图 我们在这里有一些形状 正如我们所看到的 我可以填充红色 并得到一个红色圆圈 但同时我们可以使用不同的操作 比如说不同的形状 和胶囊 比如用红色描绘 在那种情况下 我们不会得到一个填充的形状 我们填充的是形状的轮廓
但这就是我们经常想要得到的 但有时候我们发现我们可能想要 稍微有些不同的描绘 因此我们还可 比如说描绘形状的边框 而不是描绘形状 这只是个变体
这也表示所有这些描绘操作 都可以要么像第一个例子一样 占据一行的宽度 要么都是标准的描绘参数 比如 你很可能在其它图形API中看到的 破折号和终止符以及线段连接符
好的 那么我们已经了解了图形 并且我们已经了解了如何填充它们 但在这一点上 我们只使用了颜色 但其实还有其它 可以用来填充图形的功能 我们可以使用拼接图片 并且我们可以使用各种渐变色
来填充图形
这是一个使用渐变色的例子 所有渐变色样式都使用了这个 基础样式 它只提供了一维的颜色梯度 在这个例子中 我们给它提供七种颜色 它将平均地把它们排列到连续线上 正好为我们提供了梯度 一旦完成 我们可以选择 其中一种渐变样式 在这个例子中 我们要使用角渐变 我们为它提供颜色梯度 然后我们 在这个例子中 使用角渐变 我们为它提供中心点以及起始角 然后它就会在那个圆圈周围填充颜色 并把它们推到无穷以提供颜色填充 但很明显 我们可使用刚做好的样式 并把它应用到圆圈中 在这个例子中 执行填充 跟我们之前见过的一样 现在我们拥有这个颜色漂亮的轮子 而不是红色圆圈
但当然了 填充只是其中一个操作 同样地 我们刚才也只提到描绘边框 并得到一个填充颜色的戒指
好的 这就是基础信息 我们已经了解了绘制单一物体 但现在我们想继续 并使用多个绘图操作 创建更复杂的东西 多个视图 这是我们要在接下来的演讲中 使用的例子 它其实是一段时期代码 你可以下载 并且它是个交互性的饼图 它由一群颜色楔形构成 你可以添加并移除它们 它们可以动态出入
好的 在我们了解如何绘制它之前 我们需要看一下数据 我们的示例app给我们提供了一个 数据模型 并且它非常简单 它只是个卡扣 代表其中一个楔形 并且每个楔形都包含代表 视图的集合图形和颜色的 一些属性 然后我们有一大堆楔形 通过ID进行追踪 最后是一组ID 从而我们知道要按哪个顺序 把它们绘制进去 现在我们可以继续并考虑如何绘制了
正如我们之前所看到的 我们真的希望它能与布局系统相交互 因此我们要假设整个整个控制 都有一个布局边界
因为我们希望它能重新调整尺寸 并按预期四处移动 如果你思考一下要如何实现 我们可以分别绘制 每一个带颜色的楔形 只要它们适合同一个布局边界即可 然后我们把它们组合到一起 它们就可以无缝对齐了
那其实意味着我们只需要 考虑一个就可以了
我们之前看到过这样的东西了 其实就是一些图形 填充了一些渐变色 在这个例子中 一个这样的图形 但我们其实不想要这个在 SwiftUI工具箱中嵌入的图形 但那不是问题 我们可以继续 并定义一个自定义图形
自定义图形与自定义视图很相似 是遵守协议的类型 除了 在这个例子中 我们不遵守视图协议 我们使用图形协议 形状协议有一个的要求 就是路径和矩形函数 你在这里看到的矩形是布局边界 或引用框架 我猜是这样 然后它会返回贝塞尔曲线路径
因此对于自定义图形来说 我们给它提供一个属性 即楔形描述 包含几何图形 此外 我们只需要创建一条空路径 因为我们要在它里面放东西 然后稍后再返回它 为了稍微简化这个过程 我还用了帮助 它提取了我们要绘制的图形的 一些几何图形 只是为了隐藏正弦和余弦 因为这是圆形 以及诸如此类的操作 但它定义了某些变量 我们接下来可以在这个函数中使用
首先我们要添加一个内弧形 然后在路径中添加一条线 连接内外圆形 然后另一个弧线 在外侧 最后 我们就可以告诉路径说 嘿 关闭当前子路径 那将会把终点和起点连接起来 然后我们就画好形状了
现在我们可以继续 并着手绘制这个图形了 我们可以填充渐变色 大多数情况下会这样做 但我们还有一件事要做 我们在动画中看到了 我们希望图形是动态的 如果我们只按原样使用图形 SwiftUI没办法让它动起来 因为它不了解足够多的类型 因此我们可以继续并给我们的自定义 图形添加一个额外的属性 叫做可动画数据 这会提供一个矢量 包含浮点型数字 是系统可以插入的矢量 在这个例子中 我们要把这个责任 委托给数据模型 因为它替我们实施这个属性 但其实非常简单 获取三个属性和楔形描述 然后把它们结合到一个 可以进行插入的值中
好的 现在我们的图形其实已完成 我们可以把它绘制出来 我们可以退一步思考我们如何 把这些堆砌在一起做成图表
我们可以看到我们可以使用渐变色 角渐变色 用它来填充我们的图形 但这只是其中一个形状 我们想要要八个形状 并把它们组合在一起 我们可以通过一个 ZStack来实现 类似Dave讲过的HStack和 VStack 但它把东西堆砌一起 深度对应空间 我们要创建另一个自定义视图 这一次我们的视图 将通过环境获取数据模型 我们已经在其它地方设置好了 我们要从创建Zstack开始
现在我们看到在数据模型上 它提供了一组楔形ID
因此我们可以在SwiftUI中 结合ForEach视图来使用它们 那会映像到那组ID 并为每一个我们想要创建的楔形 都创建一个视图 这个楔形视图非常简单 它其实只是一个陈述视图 创建自定义图形 并填充渐变色
好的 几乎要完成了 由于SwiftUI 对依赖关系的追踪方式 当我们的数据模型更新时 视图也会更新 因为Zstack 处理插入和移除转换 它们会干净利落地淡入和淡出 这对于这样一个app来说非常好 但我们还要做一些其它的操作 我们在动画中看到了 我们希望能在你轻触楔形时 删除它
我们可以添加一个 叫做轻触操作的功能 这是视图的一个事件处理器 它表达的是如果你轻触 视图的形状的内部 就运行闭包 在那种情况下 我们要使用的闭包是启动动画 然后请求数据模型说 嘿 移除这个楔形ID 一旦我们完成 我们就可以轻触楔形了
现在我还要在这里做最后一个操作 我说过默认转换是淡入淡出效果 这对于许多东西来说都很不错 但在我们的例子中 我们想要实现更有趣的效果 我们要让楔形朝中心按比例缩小 并淡出它们 我们可以通过添加一个叫做 scaleAndFade的自定义转换实现 这是需要我们自己创建的东西
好的 思考一下这个转换是什么效果 我们希望当添加视图时 我们希望它们从缩小的比例开始 并淡出 以动画效果进入 它们将进入并放大到常规状态 然而它们位于视图等级中 它们正好会坐落在那里 最后当移除它们时 转换效果相反 如果你思考一下 很明显 我们不需要定义全部那些框架 因为我们有动画系统 因此我们只需要定义结束状态 动画系统会替我们执行其余操作 但当然了 在这个例子中 实际上有一个对称转换 因此我们实际上有两个结束状态 我们设置了转换和移除状态 并且我们有常规状态 但其实并没有发生什么
那么现在我们知道要定义哪个状态 我们可以在代码中定义它们
在SwiftUI中我们的实现方式 是通过一个叫做视图修饰器的工具 现在视图修饰器有点像视图一样 在视图修饰器中定义了一些视图等级 但它是根据一些其它视图进行定义的 这就是它所表达的东西 它有主体方法 与视图有主体属性一样 但在这个例子中 主体方法是另一个视图的函数 这就是内容参数 在这里我们可以做的是把这个应用到 任意其它视图中并应用一些变更 在我们的例子中我们想要转换效果 我们有两个转换状态 我们为它提供一个布尔值属性 比如转换是活跃的吗? 当转换是活跃的时 我们将应用两个现有的修饰器 来修改即将进入的视图 使其采用转换效果 我们把那叫做按比例缩小 并且当它设置妥了之后就让它淡出
好的 这就是如何定义转换 但我们还有最后一步
我们现在有视图修饰器 但我们需要 为系统提供视图修饰器的两个值 活跃值和不活跃值 从而SwiftUI可以 把它们打包到一次转换中 然后当添加或移除时 选择正确的值在正确的时间应用 然后在动画过程中 在它们之间进行插入
这就是我们可以继续并使用的东西 完成上述一切操作之后 我们现在可以看到我们创建了什么 作为一个演示
好的 你可以下载这个app 我要运行它 但愿如此 是的 那么这里是窗口
目前是空的 因为数据模型是空的 但我可以添加 你可以看到它们正在采用 我刚创建的转换 它们按比例放大并淡入 最棒的是我们可以轻触并移除它们 正如你所看到的 当我从中间移除 某个楔形时 它会进行漂亮的旋转 这是由于我们定义形状的方式 然后我可以开启这里的背景动画
然后在背景动画上运行着 物理仿真图形 它随机穿行在参数空间中
这是个很好的小app 即使它是动态的 但很明显它仍然是交互式的 测试是正确地运行 有意思的是当你思考 我们是如何渲染这个时 SwiftUI会为出现在屏幕上的 每一个元素 都创建一个原生的平台视图 比如UI指示器NSView 因此这与按钮类似 一般来说 这就是我们想要的效果 因为我们大部分时候是 处理常规控件之类的东西 但对于诸如所显示的这个图形 一样的东西 如果你在UIKit或 AppKit中绘制了它 这很可能不是你会做的事 你很可能不会 为每一个元素都创建 一个NSView 原因是 一旦你开始创建那么多NSView 性能可能会很差 这并不是个问题 因为我们并不打算 这么用NSView 我们在SwiftUI中有个方案 就是我们可以把一切 都放到这里的ZStack中
放在一个绘制小组内 绘制小组是一种特殊的渲染方式 仅适用于诸如图形这样的元素 那么图形和文本和图片 类似这样的 当我们这么做之后 我们实际上 会把所有SwiftUI视图 扁平化到NSViewer UI视图中 并用Metal对它们进行渲染 因此当我开始这样做时 你可以看到它的动作完全相同 因为它不是行为上的变化 但一旦我开始增加元素的数量时 你们可以看到 性能变得更好了 因为…
这仅仅是因为只有一个视图 就是视图系统想要的视图 但所发生的绘制 仅适用了一次硬件加速
那么我想这就是全部内容了 很酷
好的 在本场演讲中 我们了解了一些图形修饰器 但我想指出其实还有更多修饰器 我们做了很多工作来实施 你能在常规的2D绘图系统中 所能找到的一切 正如我们所说的 它们都适用于视图 因此如果这个 如果你需要 本场演讲中的某些信息 请查看文档
我认为这真的清晰地讲明了 我们所创建的模型的功能 并且我们想使用这些图形 但是要与其余的API一起使用 比如布局、动画和交互 SwiftUI的主旨就是我们围绕 一个视图协议统一了全部区域 在同样的程序包中我你提供一切功能 我们认为这将非常强大 我们真的已经迫不及待地看到 你们即将把它带到哪里去 谢谢大家
我们今天还有一场演讲 距离开始不到一小时了 因此如果你有任何疑问 请参加我们的演讲 谢谢
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。