SwiftUI直通车系列(5)—— 自定义绘制

SwiftUI直通车系列(5)—— 自定义绘制

前情回顾:

SwiftUI直通车系列(1)—— 视图的布局与组织

SwiftUI直通车系列(2)—— 列表视图

SwiftUI直通车系列三(3)—— 使用导航

SwiftUI直通车系列(4)—— 处理用户交互

    在UI开发中,我们经常会使用到各式各样的图标或图形。通常,我们可以直接使用图片来渲染图形,在SwiftUI中也提供了相关的接口来对图形绘制提供支持,理论上,我们可以不使用外部图片来自定义绘制出我们想要渲染的图形。

一、图形绘制

    首先,在定义SwiftUI组件时,我们可以通过路径的定义绘制其要表现的UI图形,例如要在页面上显示一个菱形图形,示例代码如下:

1struct DrawTestView:View { 2 var body: some View { 3 Path { path in 4 let width = 200 5 let height = 200 6 path.move(to: CGPoint(x: width, y: height)) 7 path.addLine(to: CGPoint(x: 100, y: 400)) 8 path.addLine(to: CGPoint(x: 200, y: 600)) 9 path.addLine(to: CGPoint(x: 300, y: 400)) 10 }.fill(Color.red) 11 } 12} 13 14struct ContentView_Previews: PreviewProvider { 15 static var previews: some View { 16 DrawTestView() 17 } 18}

效果如下图所示:

上面的代码很好理解,使用Path在定义View时,move方法用来进行绘制点的移动,简单理解,如果我们将图形的绘制类比与用笔作画,则move方法的作用就是移动笔尖的位置。addLine方法用来向视图上画一条线,定义完了路径后,调用fill方法用来进行图形内部颜色的填充。如上代码所示,实际上我们只画了三条线,系统默认将三条线及最后一个点与原点的连线组成的图形内部进行了颜色的填充,如果我们不对内部进行颜色填充,只将线的颜色显示出来,就更加直观了,代码如下:

1struct DrawTestView:View { 2 var body: some View { 3 Path { path in 4 let width = 200 5 let height = 200 6 path.move(to: CGPoint(x: width, y: height)) 7 path.addLine(to: CGPoint(x: 100, y: 400)) 8 path.addLine(to: CGPoint(x: 200, y: 600)) 9 path.addLine(to: CGPoint(x: 300, y: 400)) 10 }.stroke(Color.red,lineWidth: 10) 11 } 12}

效果如下图所示:

与addLine的使用方法类似,我们还可以通过添加矩形、椭圆、贝塞尔曲线等等方法来绘制图形,示例代码如下:

1struct DrawTestView:View { 2 var body: some View { 3 Path { path in 4 let width = 200 5 let height = 200 6 path.move(to: CGPoint(x: width, y: height)) 7 path.addLine(to: CGPoint(x: 100, y: 400)) 8 path.addLine(to: CGPoint(x: 200, y: 600)) 9 path.addLine(to: CGPoint(x: 300, y: 400)) 10 path.addRect(CGRect(x: 20, y: 20, width: 30, height: 30)) 11 path.addEllipse(in: CGRect(x: 60, y: 20, width: 60, height: 30)) 12 path.addCurve(to: CGPoint(x: 100, y: 100), control1: CGPoint(x: 160, y: 100), control2: CGPoint(x: 60, y: 80)) 13 path.addRoundedRect(in: CGRect(x: 140, y: 20, width: 50, height: 40), cornerSize: CGSize(width: 20, height: 20)) 14 }.stroke(Color.red,lineWidth: 3) 15 } 16}

效果如下图所示:

二、设置绘制属性

    在SwiftUI中,完成了图形的定义是一步,之后我们还需要将图形描边绘制或填充绘制。无论是描边绘制还是填充绘制,我们都可以定制化的对绘制属性进行控制,例如下面的示例代码:

1struct DrawTestView:View { 2 var body: some View { 3 VStack { 4 Path { path in 5 let width = 200 6 let height = 0 7 path.move(to: CGPoint(x: width, y: height)) 8 path.addLine(to: CGPoint(x: 100, y: 200)) 9 path.addLine(to: CGPoint(x: 200, y: 400)) 10 path.addLine(to: CGPoint(x: 300, y: 200)) 11 path.addLine(to: CGPoint(x: 200, y: 0)) 12 }.stroke(style: StrokeStyle(lineWidth: 3, lineCap: CGLineCap.butt, lineJoin: .bevel, miterLimit: 2, dash: [15,4], dashPhase: 2)).foregroundColor(.blue) 13 Path { path in 14 let width = 200 15 let height = 20 16 path.move(to: CGPoint(x: width, y: height)) 17 path.addLine(to: CGPoint(x: 100, y: 220)) 18 path.addLine(to: CGPoint(x: 200, y: 420)) 19 path.addLine(to: CGPoint(x: 300, y: 220)) 20 }.fill(LinearGradient(gradient: Gradient(colors: [Color.red, Color.blue]), startPoint: .top, endPoint: .bottom)) 21 } 22 } 23}

效果如下图所示:

对于描边绘制,我们可以设置线的风格,间距,转角风格等。对于填充绘制,我们可以为其设置渐变填充,上面代码示例的是线性渐变效果,系统还提供了圆心渐变等功能。

三、简单的图形变换和组合

    有规律的对绘制的图形进行变换和组合往往可以得到非常美观的复合图形,例如对于上面绘制的菱形,我们可以通过修改透明度进行图形组合,并使用旋转变换的方式使其构建出更加美观的图标,修改代码如下:

1struct DrawTestView:View { 2 let angle:Angle 3 var body: some View { 4 Path { path in 5 let width = 250 6 let height = 150 7 path.move(to: CGPoint(x: width, y: height)) 8 path.addLine(to: CGPoint(x: 100, y: 300)) 9 path.addLine(to: CGPoint(x: 200, y: 450)) 10 path.addLine(to: CGPoint(x: 300, y: 100)) 11 }.fill(LinearGradient(gradient: Gradient(colors: [Color.red, Color.blue]), startPoint: .top, endPoint: .bottom)).rotationEffect(angle, anchor: .center) 12 } 13} 14 15struct DrawContent:View { 16 var body: some View { 17 ZStack{ 18 ForEach(0 ..< 10) { i in 19 DrawTestView(angle: Angle(degrees:Double(36*i))).opacity(0.3) 20 } 21 } 22 } 23} 24 25struct ContentView_Previews: PreviewProvider { 26 static var previews: some View { 27 DrawContent() 28 } 29}

效果如下图所示:

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

SwiftUI直通车系列(3)—— 使用导航

SwiftUI直通车系列三(3)——使用导航  关于SwiftUI,我们前两篇博客介绍了独立组件的布局与属性设置相关内容,并且介绍了开发中最常用的列表视图的使用。但是一个完整的应用程序不可能是单界面的,如何使用SwiftUI进行界面间的导航跳转,是我们本博客讨论的重点。前两篇博客地址如下:Swi

SwiftUI直通车系列(4)—— 处理用户交互

SwiftUI直通车系列(4)——处理用户交互前情回顾:SwiftUI直通车系列(1)——视图的布局与组织(https://my.oschina.net/u/2340880/blog/4529951)SwiftUI直通车系列(2)——列表视图(https://my.oschina.n

SwiftUI直通车系列(1)—— 视图的布局与组织

SwiftUI直通车系列(1)——视图的布局与组织一、引言    SwiftUI提供了一种更快、更高效也更简单的页面开发方式。我们知道相对于ObjectiveC,Swift语言本身就更加高效简洁,SwiftUI采用了结构化的布局方式,使得应用的界面开发更加直观快速。本系列博客,