swift -- Quartz 2D -- 绘制图层:线条, 三角形, 矩形, 圆, 弧, 扇形, 虚线等

前面已经讲解了Quartz 2D的原理, 那么下面就来利用Quart 2D来画一些最基本的图形;

步骤

  • 获取图形上下文
  • 创建路径(描述路径)
  • 绘制图形
  • 把路径添加到上下文
  • 利用图形上下文将绘制的所有内容渲染显示到view上面

获取图形上下文

  • 新建一个类,继承自UIView
  • 实现- (void)drawRect:(CGRect)rect方法,然后在这个方法中进行获取上下文的操作步骤
    注意:
    - 只有在在drawRect:方法中才能取得跟view相关联的图形上下文
    - drawRect:方法在view第一次显示到屏幕上时调用
    - 或者手动调用view的setNeedsDisplay或者setNeedsDisplayInRect:时会调用drawRect:方法
    - 注意手动 [self drawRect] 是无效的写法

画线条

1.直线
方法一:

 override func draw(_ rect: CGRect) {
        // 获取当前的图形上下文
        let context = UIGraphicsGetCurrentContext()

        // 设置线条的属性
        // 1.设置线宽
        context?.setLineWidth(20)
        // 2.设置线条的颜色
        context?.setStrokeColor(UIColor.brown.cgColor)
        /**
         *miter,切角
         *round,圆角
         *bevel
         */
        // 3.设置顶角样式
        context?.setLineCap(.round)
        // 创建路径
        let path = CGMutablePath()
        // 给路径设置起点(开始画线,需要将起点移动到指定的point)
        path.move(to: CGPoint(x: 20, y: 200))
        // 添加一根线到另一个点 (两点一线)
        path.addLine(to: CGPoint(x: 200, y: 200))
        // 将路径添加到上下文
        context?.addPath(path)
        // 渲染图形到上下文
        context?.strokePath()
  }

方法二:

override func draw(_ rect: CGRect) {
       // 获取当前的图形上下文
        let context = UIGraphicsGetCurrentContext()

        // 设置线条的属性
        // 1.设置线宽
        context?.setLineWidth(20)
        // 2.设置线条的颜色
        context?.setStrokeColor(UIColor.brown.cgColor)

        // 开始画线,需要将起点移动到指定的point
        context?.move(to: CGPoint(x: 20, y: 200))
        // 添加一根线到另一个点 (两点一线)
        context?.addLine(to: CGPoint(x: 200, y: 200))
        // 渲染图形到上下文
        context?.strokePath()
  }

方法三:

override func draw(_ rect: CGRect) {
//UIKIT 封装的绘图功能  贝斯曲线
// 获取贝塞尔路径
        let path = UIBezierPath()
        // 设置起点
        path.move(to: CGPoint(x: 20, y: 200))
        // 添加一根线到终点
        path.addLine(to: CGPoint(x: 200, y: 200))
        // 绘制路径
        path.stroke()
}

线宽20 线顶角为round 如下图
这里写图片描述

2.折线

override func draw(_ rect: CGRect) {
        // 获取当前的图形上下文
        let context = UIGraphicsGetCurrentContext()

        // 设置线条的属性
        // 1.设置线宽
        context?.setLineWidth(20)
        // 2.设置线条的颜色
        context?.setStrokeColor(UIColor.brown.cgColor)
        // 开始画线,需要将起点移动到指定的point
        context?.move(to: CGPoint(x: 20, y: 200))
        // 添加一根线到另一个点 (两点一线)
        context?.addLine(to: CGPoint(x: 200, y: 200))
        context?.addLine(to: CGPoint(x: 200, y: 380))
        // 渲染图形到上下文
        context?.strokePath()
}

线宽20 顶角为round 如下图
这里写图片描述

说到这里,用两幅图区分一下setLineCap和setLineJoin这两个方法:
这里写图片描述这里写图片描述

3.曲线
Quartz 使用计算机图形学中的多项式来绘制曲线,支持二次和三次曲线;

利用move(to: beginPoint)来设定曲线起点
利用addQuadCurve(to: endPoint, control: controlPoint)来绘制二次曲线
利用addCurve(to: endPoint, control1:control1Point, control2: control2Point)来绘制三次曲线
注: beginPoint为曲线起点, endPoint为曲线终点, controlPoint为控制曲线的点

原理图入下图所示
这里写图片描述
这里写图片描述

具体代码:

// 二次曲线
override func draw(_ rect: CGRect) {
        // 获取当前的图形上下文
        let context = UIGraphicsGetCurrentContext()

        context?.move(to: CGPoint(x: 100, y: 0))
        context?.addQuadCurve(to: CGPoint(x: 300, y: 0), control:CGPoint(x: 200, y: 100))
context?.strokePath()
    }

模拟器效果:
这里写图片描述

// 三次曲线
// 连续画三条
override func draw(_ rect: CGRect) {
        // 获取当前的图形上下文
        let context = UIGraphicsGetCurrentContext()
        context?.move(to: CGPoint(x: 10, y: 100))
        context?.addCurve(to: CGPoint(x: 50, y: 100), control1: CGPoint(x: 20, y: 50), control2: CGPoint(x: 40, y: 150))
        // 接上一个终点开始画线
        context?.move(to: CGPoint(x: 50, y: 100))
        context?.addCurve(to: CGPoint(x: 90, y: 100), control1: CGPoint(x: 60, y: 50), control2: CGPoint(x: 80, y: 150))
        // 接上一个终点开始画线
        context?.move(to: CGPoint(x: 90, y: 100))
        context?.addCurve(to: CGPoint(x: 130, y: 100), control1: CGPoint(x: 100, y: 50), control2: CGPoint(x: 120, y: 150))
        context?.strokePath()
   }

模拟器效果:
这里写图片描述

4.三角形
只要三个点就行跟画一条线方式一样,把三点连接起来
代码如下:

override func draw(_ rect: CGRect) {
        // 获取当前的图形上下文
        let context = UIGraphicsGetCurrentContext()
        // 设置边框颜色
        context?.setStrokeColor(UIColor.green.cgColor)
        // 设置填充颜色
        context?.setFillColor(UIColor.brown.cgColor)
        // 开始画线,需要将起点移动到指定的point
        context?.move(to: CGPoint(x: 20, y: 200))
        // 添加一根线到另一个点 (两点一线)
        context?.addLine(to: CGPoint(x: 200, y: 200))
        // 添加一根线到另一个点 (两点一线)
        context?.addLine(to: CGPoint(x: 200, y: 100))

        // 画线完毕,最后将起点和终点封起来
        context?.closePath()
        /*
            stroke      : 边框;
            fill        : 填充
            fillStroke  : 边框 + 填充
         */
        context?.drawPath(using: .fillStroke)
        // 渲染上下文
        context?.strokePath()
    }

模拟器效果:
这里写图片描述

5.四边形
和三角形的原理一样 确定四个点连线
代码如下:

override func draw(_ rect: CGRect) {
        // 获取当前的图形上下文
        let context = UIGraphicsGetCurrentContext()

        // 开始画线,需要将起点移动到指定的point
        context?.move(to: CGPoint(x: 20, y: 200))
        // 添加一根线到另一个点 (两点一线)
        context?.addLine(to: CGPoint(x: 200, y: 200))
        // 添加一根线到另一个点 (两点一线)
        context?.addLine(to: CGPoint(x: 200, y: 100))
        // 添加一根线到另一个点 (两点一线)
        context?.addLine(to: CGPoint(x: 20, y: 100))

        // 画线完毕,最后将起点和终点封起来
        context?.closePath()

        // 渲染上下文
        context?.strokePath()
    }

模拟器效果:
这里写图片描述

6.弧,扇形,圆
在swift里面,有两个画圆弧的方法:

/*
 ** 这个方法是根据圆点和半径来确定圆的位置和大小,根据Angle来确定圆弧的起点和终点
 ** center: 圆点
 ** radius: 半径
 ** startAngle: 开始的弧度
 ** endAngle: 结束的弧度
 ** clockwise: 0为顺时针,1为逆时针
 */
context?.addArc(center: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: clockwise)
/*
 ** 这个方法通过两个切点和半径,来确定一段圆弧
 ** tangent1End: 圆弧的第一个切点
 ** tangent2End: 圆弧的第二个切点
 ** radius: 圆弧的半径
 */
context?.addArc(tangent1End: tangent1End, tangent2End: tangent2End, radius: radius)

注: 圆弧绕一周,其实就是一个圆, 而扇形是圆弧的两个端点和圆点的连线,形成一个封闭的图形
在swift中,可以用上述两种方法,分别画出圆,圆弧以及扇形
* 方法一:*
代码如下:

override func draw(_ rect: CGRect) {
        // 获取当前的图形上下文
        let context = UIGraphicsGetCurrentContext()
// 画圆
        context?.addArc(center: CGPoint(x: 100, y: 100), radius: 50, startAngle: CGFloat( -30 / 180.0 * Double.pi), endAngle: CGFloat( 330.0 / 180.0 * Double.pi), clockwise: false)
        context?.move(to: CGPoint(x: 150, y: 100))

        // 扇形
        context?.move(to: CGPoint(x: 100, y: 200))
        context?.addArc(center: CGPoint(x: 100, y: 200), radius: 50, startAngle: CGFloat( 30 / 180.0 * Double.pi), endAngle: CGFloat( 330.0 / 180.0 * Double.pi), clockwise: true)
        context?.addLine(to: CGPoint(x: 100, y: 200))

        // 第二个圆
        context?.addArc(center: CGPoint(x: 100, y: 300), radius: 50, startAngle: CGFloat( 0 / 180.0 * Double.pi), endAngle: CGFloat( 360 / 180.0 * Double.pi), clockwise: false)

        // 第三个圆
        context?.move(to: CGPoint(x: 150, y: 400))
        context?.addArc(center: CGPoint(x: 100, y: 400), radius: 50, startAngle: CGFloat( 0 / 180.0 * Double.pi), endAngle: CGFloat( 360 / 180.0 * Double.pi), clockwise: false)

        // 第一个圆弧
        context?.move(to: CGPoint(x: 150, y: 500))
        context?.addArc(center: CGPoint(x: 100, y: 500), radius: 50, startAngle: CGFloat( 0 / 180.0 * Double.pi), endAngle: CGFloat( 45 / 180.0 * Double.pi), clockwise: true)
        // 第二个圆弧
        context?.move(to: CGPoint(x: 150, y: 600))
        context?.addArc(center: CGPoint(x: 100, y: 600), radius: 50, startAngle: CGFloat( 0 / 180.0 * Double.pi), endAngle: CGFloat( 45 / 180.0 * Double.pi), clockwise: false)
        context?.strokePath()
}

虚拟机效果图
这里写图片描述

通过上图的效果展示, 总结如下:
1.当startAngle为0,即标准的起始点在3点钟的位置;
2.在同一块context上画两个圆的时候,当第一个圆画完之后,要将point转移到下一个圆的起始点(根据startAngle的不同,以及圆点和半径的位置计算出来)
3.画圆的轨迹要根据clockwise来决定,false表示顺时针,true表示逆时针
4.startAngle/endAngle的弧度大小,是顺时针方向的

* 方法二:*
代码如下:

override func draw(_ rect: CGRect) {
        // 获取当前的图形上下文
        let context = UIGraphicsGetCurrentContext()
        // 画正方形带弧度
        context?.move(to: CGPoint(x: 110, y: 100))
        context?.addArc(tangent1End: CGPoint(x: 200, y: 100), tangent2End: CGPoint(x: 200, y: 200), radius: 10.0)
        context?.addArc(tangent1End: CGPoint(x: 200, y: 200), tangent2End: CGPoint(x: 100, y: 200), radius: 10.0)
        context?.addArc(tangent1End: CGPoint(x: 100, y: 200), tangent2End: CGPoint(x: 100, y: 100), radius: 10.0)
        context?.addArc(tangent1End: CGPoint(x: 100, y: 100), tangent2End: CGPoint(x: 200, y: 100), radius: 10.0)
        // 画圆
        context?.move(to: CGPoint(x: 200, y: 300))
        context?.addArc(tangent1End: CGPoint(x: 300, y: 300), tangent2End: CGPoint(x: 300, y: 400), radius: 100)
        context?.addArc(tangent1End: CGPoint(x: 300, y: 500), tangent2End: CGPoint(x: 200, y: 500), radius: 100)
        context?.addArc(tangent1End: CGPoint(x: 100, y: 500), tangent2End: CGPoint(x: 100, y: 400), radius: 100)
        context?.addArc(tangent1End: CGPoint(x: 100, y: 300), tangent2End: CGPoint(x: 200, y: 300), radius: 100)
        context?.strokePath()
        // 画虚线
        context?.move(to: CGPoint(x: 100, y: 300))
        context?.setLineDash(phase: 0, lengths: [5,10])
        context?.addLine(to: CGPoint(x: 300, y: 300))
        context?.addLine(to: CGPoint(x: 300, y: 500))
        context?.addLine(to: CGPoint(x: 100, y: 500))
        context?.addLine(to: CGPoint(x: 100, y: 300))
        context?.strokePath()
    }

效果图:
这里写图片描述

分析红线部分代码:

// 由上句代码知道  point已经走到CGPoint(x: 100, y: 400) 这个点, 那么下面这句代码之后, 确定了切线一和切线二, 切线一就是(100,400)和(100,300)两点的连线, 切线二是(100,300)和(200,300)的连线,半径为100,我们可以分析出,圆点在(200,400),圆弧就如图所示
context?.addArc(tangent1End: CGPoint(x: 100, y: 300), tangent2End: CGPoint(x: 200, y: 300), radius: 100)

Quartz 2D的强大毋庸置疑,我在这里也只是做了一些简单的应用,也是本人通过效果图的展示结果做出的一些理解,可能会存在一些错误, 还请大家多多指点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
org.quartz-scheduler:quartz:2.3.2是一个Maven坐标,用于引入Quartz任务调度框架的相关依赖。你可以在你的项目中的pom.xml文件中添加如下依赖来引入Quartz 2.3.2版本: <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version> </dependency> 这个坐标代表了Quartz框架的版本号为2.3.2,可以通过Maven自动下载相关的jar包。 如果你想查看在你的项目中使用了org.quartz-scheduler:quartz:2.3.2版本后的依赖树,你可以使用命令"mvn dependency:tree"来查看。这个命令会列出项目的所有依赖关系,包括间接依赖。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [org.quartz](https://blog.csdn.net/qq_40144701/article/details/112540359)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [quartz-2.3.2-API文档-中文版.zip](https://download.csdn.net/download/qq_36462452/85549591)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [因为org.quartz-scheduler-quartz定时任务引入版本过高导致项目启动报错问题](https://blog.csdn.net/chengzhan9657/article/details/100839563)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值