前言
在 SwiftUI 中,你可以使用 Shape
的 API 去绘制你所需要的 2D 图形。但最终,SwiftUI 框架会将你绘制的所有图形转换为 SwiftUI 视图并去渲染它们。这种方法有利有弊,当我们需要绘制复杂的图形时,我们需要组合多个简单图形去实现。
但现在,我们可以在不组合多个形状的情况下绘制丰富的 2D 图形。这就需要使用到我们接下来要介绍的 Canvas
视图。
简单使用
Canvas
视图支持即时模式绘制,无需使用 Shape
API。我们可以用它来画任何我们想要的东西,以一种程序化的方式,逐行绘制。让我们看一个下面的这个小例子。示例代码如下:
1 | less复制代码struct ContentView: View { |
效果图如下:
正如你在上面的例子中看到的,我们创建了一个 Canvas
视图作为 ContentView
的根视图。它接受一些参数,允许我们用不透明、颜色模式和异步渲染选项配置画布。
我们应该把所有的绘图逻辑放在传递给 Canvas
视图的闭包中。这个闭包称为渲染器。渲染器闭包为我们提供了一个 GraphicalContext
的实例,我们用它来绘制内容和画布的大小。
GraphicsContext
类型的实例是渲染器闭包的 inout
参数。这意味着我们可以在绘制内容时对其进行适当的修改。比如我们在当前圆形的左上角再绘制一个紫色小圆形,示例代码如下:
1 | less复制代码struct ContentView: View { |
效果图如下:
如上图所示,我们调整了上下文的不透明度,它影响了该线之后出现的所有绘图逻辑。GraphicsContext
类型允许我们调整许多绘图过程参数,如不透明度、缩放和混合模式。它还允许我们使用 addFilter
函数添加不同的过滤器。
GraphicsContext
类型提供描边、填充和剪辑功能,允许我们绘制任何需要的路径。但它也提供了绘制功能,允许我们绘制文本和图像。
绘制文本和图像
需要注意的是,我们不能直接通过 Canvas
绘制文本或图像类型的实例。我们应该使用 GraphicsContext
类型上的 resolve
函数将它们转换为 draw
函数接受的格式。resolve
函数返回一个 ResolvedText
或 ResolvedImage
类型的实例,它允许我们调整已转换类型对象的阴影。代码示例如下:
1 | css复制代码struct ContentView: View { |
效果图如下:
你不仅可以使用 Canvas
类型来绘制文本和图像,还可以绘制任何 SwiftUI 视图。但在此之前,我们应该在创建画布时使用符号闭包来注册它们。符号闭包中的每个 SwiftUI 视图都应该有其唯一的标签,以便我们稍后在渲染器闭包中通过 id 解析视图。示例代码如下:
1 | css复制代码struct ContentView: View { |
效果图如下:
动画
Canvas
视图不支持动画,但是你可以用动画调度器把它嵌入到 TimelineView
中。示例代码如下:
1 | less复制代码struct ContentView: View { |
该代码的实际效果大家可以自行在 SwiftUI 中的预览中自行查看。
本文转载自: 掘金