UIBezierPath 完全指南

一、基础概念

UIBezierPath 是 UIKit 中用于定义矢量路径的类,可用于绘制自定义形状、实现复杂图形和动画效果。

二、基础绘制方法

1. 创建路径实例

let path =  UIBezierPath()

2. 基本图形绘制

// 矩形
 let rectPath =  UIBezierPath(rect:  CGRect(x:  0, y:  0, width:  100, height:  100))   

// 圆角矩形 
let roundedRect =  UIBezierPath(roundedRect:  CGRect(x:  0, y:  0, width:  100, height:  100),   cornerRadius:  10)   

// 圆形/椭圆 
let ovalPath =  UIBezierPath(ovalIn:  CGRect(x:  0, y:  0, width:  100, height:  100))   // 圆弧 let arcPath =  UIBezierPath(arcCenter:  CGPoint(x:  50, y:  50),   radius:  40, startAngle:  0, endAngle:  CGFloat.pi/2, clockwise:  true)

三、常用路径操作方法

1. 直线绘制

path.move(to:  CGPoint(x:  0, y:  0))  // 移动起点 
path.addLine(to:  CGPoint(x:  100, y:  100))  // 添加直线

2. 曲线绘制

// 二次贝塞尔曲线 
path.addQuadCurve(to:  CGPoint(x:  200, y:  0),   controlPoint:  CGPoint(x:  100, y:  100))  

 // 三次贝塞尔曲线 
path.addCurve(to:  CGPoint(x:  300, y:  100),   controlPoint1:  CGPoint(x:  200, y:  0), controlPoint2:  CGPoint(x:  250, y:  200))

3. 闭合路径

path.close()  // 连接最后一个点与起点

四、进阶技巧

1. 组合路径

let path1 =  UIBezierPath(rect:  CGRect(x:  0, y:  0, width:  50, height:  50)) 
let path2 =  UIBezierPath(ovalIn:  CGRect(x:  25, y:  25, width:  50, height:  50)) 
path1.append(path2)

2. 路径变换

// 缩放
 path.apply(CGAffineTransform(scaleX:  2.0, y:  1.5))  
 
// 旋转 
path.apply(CGAffineTransform(rotationAngle:  CGFloat.pi/4))   

// 平移 
path.apply(CGAffineTransform(translationX:  50, y:  100))

3. 路径布尔运算

path1.usesEvenOddFillRule =  true  // 设置填充规则

五、实用案例

1. 绘制五角星

func createStarPath(center: CGPoint, radius: CGFloat) -> UIBezierPath {
    let path = UIBezierPath()
    let pointsOnStar = 5
    
    for i in 0..<pointsOnStar * 2 {
        let angle = CGFloat(i) * .pi / CGFloat(pointsOnStar)
        let r = i % 2 == 0 ? radius : radius/2
        let point = CGPoint(x: center.x + r * sin(angle), 
                           y: center.y + r * cos(angle))
        
        if i == 0 {
            path.move(to: point)
        } else {
            path.addLine(to: point)
        }
    }
    path.close()
    return path
}

2. 绘制对话气泡

func createBubblePath(rect: CGRect, pointerSize: CGFloat) -> UIBezierPath {
    let path = UIBezierPath()
    let radius: CGFloat = 10
    
    // 顶部
    path.move(to: CGPoint(x: rect.minX + radius, y: rect.minY))
    path.addLine(to: CGPoint(x: rect.maxX - radius, y: rect.minY))
    path.addArc(withCenter: CGPoint(x: rect.maxX - radius, y: rect.minY + radius), 
                radius: radius, 
                startAngle: 3 * .pi/2, 
                endAngle: 0, 
                clockwise: true)
    
    // 右侧
    path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY - radius - pointerSize))
    
    // 气泡指针
    path.addLine(to: CGPoint(x: rect.maxX - pointerSize, y: rect.maxY - pointerSize))
    path.addLine(to: CGPoint(x: rect.maxX - pointerSize, y: rect.maxY))
    path.addLine(to: CGPoint(x: rect.maxX - 2 * pointerSize, y: rect.maxY - pointerSize))
    
    // 底部
    path.addLine(to: CGPoint(x: rect.minX + radius, y: rect.maxY - pointerSize))
    path.addArc(withCenter: CGPoint(x: rect.minX + radius, y: rect.maxY - pointerSize - radius), 
                radius: radius, 
                startAngle: .pi/2, 
                endAngle: .pi, 
                clockwise: true)
    
    // 左侧
    path.addLine(to: CGPoint(x: rect.minX, y: rect.minY + radius))
    path.addArc(withCenter: CGPoint(x: rect.minX + radius, y: rect.minY + radius), 
                radius: radius, 
                startAngle: .pi, 
                endAngle: 3 * .pi/2, 
                clockwise: true)
    
    return path
}

六、路径使用技巧

  1. 渲染路径
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.fillColor = UIColor.red.cgColor
shapeLayer.strokeColor = UIColor.blue.cgColor
shapeLayer.lineWidth = 2
view.layer.addSublayer(shapeLayer)
  1. 路径动画
let animation = CABasicAnimation(keyPath: "path")
animation.duration = 1.0
animation.toValue = newPath.cgPath
shapeLayer.add(animation, forKey: "pathAnimation")
  1. 路径检测
path.contains(point)  // 判断点是否在路径内
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容