背景

iOS开发中,经常会遇到要制作一些图形,比方矩形,圆形,椭圆,弧或许不规则的多边形,这时咱们能够经过重写UIView的draw(_ rect: CGRect)办法,然后经过UIBezierPath来制作。

UIBezierPath这个类在UIKit中, 是Core Graphics结构关于path的一个封装。

关于iOS绘图原理,能够查看博主的这篇文章 iOS底层原理之 UIView制作显示原理流程解析以及性能优化

根本属性和办法阐明

1 UIColor.red.set()

设置线条色彩,也便是画笔色彩。

2 lineWidth

线宽

3 lineCapStyle

线帽款式,是CGLineCap类型的枚举,界说如下

public enum CGLineCap : Int32, @unchecked Sendable {
    /// 指定不制作端点,即线条结尾处直接完毕。
    case butt    = 0
    /// 制作圆形端点,即线条结尾处制作一个直径为线条宽度的半圆
    case round   = 1
    /// 制作方形端点,即线条结尾处制作半个边长为线条宽度的正方形。
    /// 需要阐明的是,这种形状的端点与“butt”形状的端点十分相似,只是采用这种形式的端点的线条略长一点而已
    case square  = 2
}

作用如下,次序和枚举次序一一对应

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

4 lineJoinStyle

线衔接款式,即角落款式,是CGLineJoin类型的枚举,界说如下

public enum CGLineJoin : Int32, @unchecked Sendable {
    /// 尖角
    case miter = 0
    /// 圆角
    case round = 1
    /// 缺角
    case bevel = 2
}

作用如下,次序和枚举次序一一对应

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

5 stroke()

stroke 得到的是不被填充的view,即只会制作曲线路线。

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

6 fill()

fill 得到的内部被填充的 view,即会将曲线构成的几何图形,填充满画笔色彩。

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

制作矩形

经过init(rect: CGRect)办法制作,代码如下

override func draw(_ rect: CGRect) {
    UIColor.red.set()
    let path1 = UIBezierPath(rect: CGRect(x: 100, y: 100, width: 200, height: 100))
    path1.lineWidth = 5.0
    path1.lineCapStyle = .round
    path1.lineJoinStyle = .round
    path1.stroke()
    let path2 = UIBezierPath(rect: CGRect(x: 100, y: 230, width: 200, height: 200))
    path2.lineWidth = 5.0
    path2.lineCapStyle = .round
    path2.lineJoinStyle = .round
    path2.fill()
}

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

制作带圆角的矩形

有两种方式,假如四个角都需要圆角,能够经过init(roundedRect rect: CGRect, cornerRadius: CGFloat)办法制作。

假如只需要某些圆角,则能够经过init(roundedRect rect: CGRect, byRoundingCorners corners: UIRectCorner, cornerRadii: CGSize)办法制作。

代码如下

override func draw(_ rect: CGRect) {
    UIColor.red.set()
    let path1 = UIBezierPath(roundedRect: CGRect(x: 100, y: 100, width: 200, height: 100), cornerRadius: 10)
    path1.lineWidth = 5.0
    path1.lineCapStyle = .round
    path1.lineJoinStyle = .round
    path1.stroke()
    let path2 = UIBezierPath(roundedRect: CGRect(x: 100, y: 230, width: 200, height: 200), byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 10, height: 10))
    path2.lineWidth = 5.0
    path2.lineCapStyle = .round
    path2.lineJoinStyle = .round
    path2.fill()
}

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

制作多边形

经过move(to point: CGPoint)和addLine(to point: CGPoint)办法制作,moveToPoint:这个办法是设置开端点,意味着从这个点开端。addLineToPoint:设置想要创立的多边形经过的点,也便是两线相交的那个点,能够接连创立line,每一个line的起点都是先前的结尾,结尾便是指定的点,将线段衔接起来便是咱们想要创立的多边形了。最终第五条线是用path.close()得到的,closePath办法不仅完毕一个shape的subpath表述,它也在最终一个点和第一个点之间画一条线段,这是一个便当的办法,咱们不需要去画最终一条线了。代码如下

override func draw(_ rect: CGRect) {
    UIColor.red.set()
    let path = UIBezierPath()
    path.lineWidth = 5.0
    path.lineCapStyle = .round
    path.lineJoinStyle = .round
    path.move(to: CGPoint(x: 100, y: 300))
    path.addLine(to: CGPoint(x: 200, y: 200))
    path.addLine(to: CGPoint(x: 300, y: 300))
    path.addLine(to: CGPoint(x: 260, y: 400))
    path.addLine(to: CGPoint(x: 140, y: 400))
    path.close()
    path.fill()
}

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

制作椭圆

经过init(ovalIn rect: CGRect)办法制作,假如传入的rect是一个矩形,则得到矩形的内切椭圆,假如传入的rect是一个正方形,则得到正方形的内切圆。代码如下

override func draw(_ rect: CGRect) {
    UIColor.red.set()
    let path1 = UIBezierPath(ovalIn: CGRect(x: 100, y: 100, width: 200, height: 100))
    path1.lineWidth = 5.0
    path1.lineCapStyle = .round
    path1.lineJoinStyle = .round
    path1.stroke()
    let path2 = UIBezierPath(ovalIn: CGRect(x: 100, y: 230, width: 200, height: 200))
    path2.lineWidth = 5.0
    path2.lineCapStyle = .round
    path2.lineJoinStyle = .round
    path2.fill()
}

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

制作一段弧线

经过init(arcCenter center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool)办法制作,其间arcCenter指圆心坐标,radius指圆的半径,startAngle指圆弧的开端视点,endAngle指圆弧的完毕视点,clockwise指是否顺时针方向制作。其间圆弧的视点参考系如下

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

代码如下

override func draw(_ rect: CGRect) {
    UIColor.red.set()
    let path1 = UIBezierPath(arcCenter: CGPoint(x: 200, y: 250), radius: 100, startAngle: 180 / 180 * .pi, endAngle: 45 / 180 * .pi, clockwise: true)
    path1.lineWidth = 5.0
    path1.lineCapStyle = .round
    path1.lineJoinStyle = .round
    path1.stroke()
    let path2 = UIBezierPath(arcCenter: CGPoint(x: 200, y: 450), radius: 100, startAngle: 0, endAngle: 2 * .pi, clockwise: true)
    path2.lineWidth = 5.0
    path2.lineCapStyle = .round
    path2.lineJoinStyle = .round
    path2.fill()
}

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

制作二次贝塞尔曲线

经过addQuadCurve(to endPoint: CGPoint, controlPoint: CGPoint)办法制作,曲线段在当时点开端,在指定的点完毕,一个控制点的切线界说,图示如下

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

代码如下

override func draw(_ rect: CGRect) {
    UIColor.red.set()
    let path1 = UIBezierPath()
    path1.lineWidth = 5.0
    path1.lineCapStyle = .round
    path1.lineJoinStyle = .round
    path1.move(to: CGPoint(x: 100, y: 200))
    path1.addQuadCurve(to: CGPoint(x: 300, y: 200), controlPoint: CGPoint(x: 100, y: 100))
    path1.stroke()
    let path2 = UIBezierPath()
    path2.lineWidth = 5.0
    path2.lineCapStyle = .round
    path2.lineJoinStyle = .round
    path2.move(to: CGPoint(x: 100, y: 250))
    path2.addQuadCurve(to: CGPoint(x: 300, y: 250), controlPoint: CGPoint(x: 250, y: 400))
    path2.fill()
}

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

制作三次贝塞尔曲线

经过addCurve(to endPoint: CGPoint, controlPoint1: CGPoint, controlPoint2: CGPoint)办法制作,曲线段在当时点开端,在指定的点完毕,两个控制点的切线界说,图示如下

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

代码如下

override func draw(_ rect: CGRect) {
    UIColor.red.set()
    let path1 = UIBezierPath()
    path1.lineWidth = 5.0
    path1.lineCapStyle = .round
    path1.lineJoinStyle = .round
    path1.move(to: CGPoint(x: 100, y: 200))
    path1.addCurve(to: CGPoint(x: 300, y: 200), controlPoint1: CGPoint(x: 150, y: 50), controlPoint2: CGPoint(x: 250, y: 350))
    path1.stroke()
    let path2 = UIBezierPath()
    path2.lineWidth = 5.0
    path2.lineCapStyle = .round
    path2.lineJoinStyle = .round
    path2.move(to: CGPoint(x: 100, y: 350))
    path2.addCurve(to: CGPoint(x: 300, y: 350), controlPoint1: CGPoint(x: 150, y: 200), controlPoint2: CGPoint(x: 250, y: 500))
    path2.fill()
}

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解

制作虚线

经过setLineDash(_ pattern: UnsafePointer?, count: Int, phase: CGFloat)办法制作。

其间pattern是C款式的浮点值数组,包含线段和形式中的空隙的长度(以点为单位)。 数组中的值交替,从第一个线段长度开端,后跟第一个空隙长度,后跟第二个线段长度,依此类推。

count是形式中的值的数量,即虚线数组元素个数。

phase是虚线开端的方位,即开端制作图画的偏移量,沿着虚线图画的点测量。 例如,图画5-2-3-2的相位值phase为6将导致绘图在第一个空隙的中心开端。

代码如下

override func draw(_ rect: CGRect) {
    UIColor.red.set()
    let path1 = UIBezierPath()
    path1.lineWidth = 5.0
    path1.lineCapStyle = .round
    path1.lineJoinStyle = .round
    path1.move(to: CGPoint(x: 50, y: 200))
    path1.addLine(to: CGPoint(x: 400, y: 200))
    var dashConfig1:[CGFloat] = [10.0, 15.0]
    path1.setLineDash(&dashConfig1, count: dashConfig1.count, phase: 0)
    path1.stroke()
    let path2 = UIBezierPath()
    path2.lineWidth = 5.0
    path2.lineCapStyle = .round
    path2.lineJoinStyle = .round
    path2.move(to: CGPoint(x: 50, y: 250))
    path2.addLine(to: CGPoint(x: 400, y: 250))
    var dashConfig2:[CGFloat] = [10.0, 15.0, 15.0, 25.0]
    path2.setLineDash(&dashConfig2, count: dashConfig2.count, phase: 0)
    path2.stroke()
}

iOS-Swift知识之 UIBezierPath贝塞尔曲线常用方法详解