swift之绘图集合

 

1,什么是Core Graphics

(1)Core Graphics Framework 是一套基于 C 的 API 框架,使用了 Quartz 作为绘图引擎,可用于一切绘图操作。它提供了低级别、轻量级、高保真度的 2D 渲染。
(2)Quartz 2D 是 Core Graphics Framework 的一部分,是一个强大的二维图像绘制引擎。
(3)我们使用的 UIKit 库中所有 UI 组件其实都是由 CoreGraphics 绘制实现的。所以使用 Core Graphics 可以实现比 UIKit 更底层的功能。
(4)当我们引入 UIKit 框架时系统会自动引入 Core Graphics 框架,同时在 UIKit 内部还对一些常用的绘图 API 进行了封装,方便我们使用。 (比如:CGMutablePath 是 Core Graphics 的底层API,而 UIBezierPath 就是对 CGMutablePath 的封装。)

 

2,绘图的一般步骤

(1)获取绘图上下文

(2)创建并设置路径

(3)将路径添加到上下文

(4)设置上下文状态(如笔触颜色、宽度、填充色等等)

(5)绘制路径

 

===============context添加图片路径======================================

===============基础的绘图设置========

 

override func draw(_ rect: CGRect) {

       super.draw(rect)

        let ctx=UIGraphicsGetCurrentContext()

         ctx?.move(to: CGPoint.init(x: 100, y: 100))//绘制起点

        ctx?.addLine(to: CGPoint.init(x: 300, y: 100))//绘制第二个点

        ctx?.addLine(to: CGPoint.init(x: 300, y: 300))//第三个点

        ctx?.setLineCap(CGLineCap.butt)//设置线头的样式

        ctx?.setLineJoin(CGLineJoin.bevel)//设置连接处的样式

        ctx?.setLineWidth(10)//设置线宽

 

ctx?.setLineDash(phase: 5, lengths: [10,3])//设置虚线,phase是设置几段,lengths是设置每一个线段的长度和间隔

 

 ctx?.addRect(CGRect.init(x: 0, y:0, width: 200, height: 200).insetBy(dx: 20, dy: 20))//相对于CGRect.init(x: 0, y:0, width: 200, height: 200)向内偏移x和y方向20,20

 ctx?.setShadow(offset: CGSize.init(width: 3, height: 3), blur: 0.5, color: UIColor.blue.cgColor)//设置阴影

 

        ctx?.setStrokeColor(UIColor.red.cgColor)//设置笔触的颜色

 

        ctx?.closePath()//闭合路径

       ctx?.strokePath()//绘制路径

        

    }

 

==========填充fill========

 

 

let ctx=UIGraphicsGetCurrentContext()

         ctx?.move(to: CGPoint.init(x: 100, y: 100))//绘制起点

        ctx?.addLine(to: CGPoint.init(x: 300, y: 100))//绘制第二个点

        ctx?.addLine(to: CGPoint.init(x: 300, y: 300))//第三个点

        ctx?.setLineCap(CGLineCap.butt)//设置线头的样式

        ctx?.setLineJoin(CGLineJoin.bevel)//设置连接处的样式

        ctx?.setLineWidth(10)//设置线宽

 ctx?.closePath()//闭合路径

 ctx?.setFillColor(UIColor.red.cgColor)//设置填充颜色

        ctx?.fillPath()//填充路径

 

================绘制长方形、正方形、圆形、椭圆形==========

 

 

 let ctx=UIGraphicsGetCurrentContext()

 ctx?.addRect(CGRect.init(x: 0, y:0, width: 200, height: 200))//绘制长方形,正方形,x,y是左上角的点

        ctx?.addEllipse(in: CGRect.init(x: 100, y: 100, width: 200, height: 200))//正圆,x,y是圆的外切正方形的左上角的点

        ctx?.addEllipse(in: CGRect.init(x: 100, y: 100, width: 200, height: 100))//椭圆,x,y是椭圆外切长方形的左上角的点

  ctx?.strokePath()//绘制路径

 

==================绘图矩阵变形操作==========

 

注意:坐标变换操作必须要在添加图形之前,如果设置在添加图形之后的话会无效。

 ************平移=====

该方法相当于把原来位于 (0, 0) 位置的坐标原点平移到 (tx, ty) 点。在平移后的坐标系统上绘制图形时,所有坐标点的 X 坐标都相当于增加了 tx,所有点的 Y 坐标都相当于增加了 ty。

 let ctx=UIGraphicsGetCurrentContext()

 

  ctx?.translateBy(x: 50, y: 0)

        ctx?.addRect(CGRect.init(x: 0, y:0, width: 200, height: 200))//绘制长方形,正方形,x,y是左上角的点

 

  ctx?.strokePath()//绘制路径

***********************旋转****************

该方法控制坐标系统旋转 angle 弧度。在缩放后的坐标系统上绘制图形时,所有坐标点的 X、Y 坐标都相当于旋转了 angle弧度之后的坐标。

 

 let ctx=UIGraphicsGetCurrentContext()

 ctx?.rotate(by: 0.25*3.14)//旋转

        ctx?.addRect(CGRect.init(x: 0, y:0, width: 200, height: 200))//绘制长方形,正方形,x,y是左上角的点

ctx?.strokePath()//绘制路径

 

 

 

**************缩放**************

该方法控制坐标系统在水平方向和垂直方向上进行缩放。在缩放后的坐标系统上绘制图形时,所有点的 X 坐标都相当于乘以 sx 因子,所有点的 Y 坐标都相当于乘以 sy 因子。

 let ctx=UIGraphicsGetCurrentContext()

 ctx?.scaleBy(x: 0.5, y: 0.5)//缩放到原来的0.5倍

        ctx?.addRect(CGRect.init(x: 0, y:0, width: 200, height: 200))//绘制长方形,正方形,x,y是左上角的点

ctx?.strokePath()//绘制路径

 

***************贝塞尔曲线************

 

================CGMutablePath绘制图片路径-======================

***********二次贝塞尔曲线*********

 

 

        //获取绘图上下文

        let context = UIGraphicsGetCurrentContext()

        //创建一个矩形,它的所有边都内缩3点

        let drawingRect = self.bounds.insetBy(dx: 3, dy: 3)

        

        //创建并设置路径

        let path = CGMutablePath()

        //移动起点

        path.move(to: CGPoint(x: drawingRect.minX, y: drawingRect.maxY))

        //二次贝塞尔曲线终点

        let toPoint = CGPoint(x: drawingRect.maxX, y: drawingRect.maxY)

        //二次贝塞尔曲线控制点

        let controlPoint = CGPoint(x: drawingRect.midX, y: drawingRect.minY)

        //绘制二次贝塞尔曲线

        path.addQuadCurve(to: toPoint, control: controlPoint)

        

        //添加路径到图形上下文

        context?.addPath(path)

        

        //设置笔触颜色

        context?.setStrokeColor(UIColor.orange.cgColor)

        //设置笔触宽度

        context?.setLineWidth(6)

        

        //绘制路径

        context?.strokePath()

 

 

************三次贝塞尔曲线************

 

 //获取绘图上下文

        let context = UIGraphicsGetCurrentContext()

        //创建一个矩形,它的所有边都内缩3点

        let drawingRect = self.bounds.insetBy(dx: 3, dy: 3)

        

        //创建并设置路径

        let path = CGMutablePath()

        //移动起点

        path.move(to: CGPoint(x: drawingRect.minX, y: drawingRect.maxY))

        //三次贝塞尔曲线终点

        let toPoint = CGPoint(x: drawingRect.maxX, y: drawingRect.minY)

        //三次贝塞尔曲线第1个控制点

        let controlPoint1 = CGPoint(x: (drawingRect.minX+drawingRect.midX)/2, y: drawingRect.minY)

        //三次贝塞尔曲线第2个控制点

        let controlPoint2 = CGPoint(x: (drawingRect.midX+drawingRect.maxX)/2, y: drawingRect.maxY)

        //绘制三次贝塞尔曲线

        path.addCurve(to: toPoint, control1: controlPoint1, control2: controlPoint2)

        //添加路径到图形上下文

        context?.addPath(path)

        

        //设置笔触颜色

        context?.setStrokeColor(UIColor.orange.cgColor)

        //设置笔触宽度

        context?.setLineWidth(6)

        

        //绘制路径

        context?.strokePath()

 

================UIBezierPath设置图形路径===============

******stroke*******

 

 let bz:UIBezierPath=UIBezierPath.init()//创建路径

        bz.move(to: CGPoint.init(x: 10, y: 10))// 设置起点

        bz.addLine(to: CGPoint.init(x: 100, y: 100))//添加另外一个点

          bz.addLine(to: CGPoint.init(x: 150, y: 300))//添加另外一个点

        bz.lineWidth=5

        UIColor.red.setStroke()//设置路径颜色

 bz.lineCapStyle=CGLineCap.butt

        bz.lineJoinStyle=CGLineJoin.round

        bz.close()//闭合路径

        bz.stroke()//绘制一条线的时候用stroke,如果是图形时stroke就是空心的,fill就是填充

 

 bz.removeAllPoints()//删除画布上所有的点,如果有stroke或fill操作,不起作用

 

**********fill*******

 

 

let bz:UIBezierPath=UIBezierPath.init()//相当于创建画布

        bz.move(to: CGPoint.init(x: 10, y: 10))// 设置起点

        bz.addLine(to: CGPoint.init(x: 100, y: 100))//添加另外一个点

          bz.addLine(to: CGPoint.init(x: 150, y: 300))//添加另外一个点

        bz.lineWidth=5

       

 UIColor.red.setFill()//设置填充颜色

 bz.lineCapStyle=CGLineCap.butt

        bz.lineJoinStyle=CGLineJoin.round

        bz.close()//闭合路径

       

 

 bz.fill()//填充

 

****************绘制矩形**********

 

方法一:画四条直线

方法二:

let bz:UIBezierPath=UIBezierPath.init(rect: CGRect.init(x: 10, y: 10, width: 100, height: 100))//普通矩形

 

方法三:     let bz:UIBezierPath=UIBezierPath.init(roundedRect: CGRect.init(x: 10, y: 10, width: 100, height: 100), cornerRadius: 5)//圆角矩形

 

方法四:  let bz:UIBezierPath=UIBezierPath.init(roundedRect: CGRect.init(x: 10, y: 10, width: 100, height: 100), byRoundingCorners: UIRectCorner.topLeft, cornerRadii: CGSize(width: 10, height: 10))//单角圆弧矩形

 

  bz.fill()

 

===========圆形、椭圆======

方法一:

 let bz:UIBezierPath=UIBezierPath.init(ovalIn: CGRect.init(x: 100, y: 100, width: 50, height: 50))

 

 

方法二: /*

         参数解释:

         1.center: CGPoint  中心点坐标

         2.radius: CGFloat  半径

         3.startAngle: CGFloat 起始点所在弧度

         4.endAngle: CGFloat   结束点所在弧度

         5.clockwise: Bool     是否顺时针绘制

         7.画圆时,没有坐标这个概念,根据弧度来定位起始点和结束点位置。M_PI即是圆周率。画半圆即(0,M_PI),代表0到180度。全圆则是(0,M_PI*2),代表0到360度

         */

        

      

        let bz:UIBezierPath=UIBezierPath.init(arcCenter: CGPoint(x: 50, y: 50), radius: 50, startAngle: CGFloat(Double.pi) * 0, endAngle: CGFloat(Double.pi) * 2, clockwise: true)

       

        bz.fill()

 

 

 

 

=========二阶、三阶贝塞尔曲线==========

 

  //二阶贝塞尔曲线

        let bz = UIBezierPath.init()

        bz.move(to: CGPoint.init(x: 0, y: 0))

        bz.addQuadCurve(to: CGPoint.init(x: 100, y: 100), controlPoint: CGPoint.init(x: 200, y: 400))

 

 

 

 //三阶贝塞尔曲线

        let bz1 = UIBezierPath.init()

        bz1.move(to: CGPoint.init(x: 10, y: 10))

        bz1.addCurve(to: CGPoint.init(x: 50, y: 50), controlPoint1: CGPoint.init(x: 50, y: 80), controlPoint2: CGPoint.init(x: 80, y: 120))

        bz1.stroke()

 

 

=========CAShapeLayer绘图=======

 

   1.CAShapeLayer继承CALayer,可以使用CALayer的全部属性.

   2.CAShapeLayer需要配合贝塞尔曲线使用, CAShapeLayer需要贝塞尔曲线的path

  3.使用CAShapeLayer与贝塞尔曲线可以实现不在view的drawRect方法中画出一下想要的图形, drawRect 是属于Core Graphics框架走CPU,比较耗性能. CAShapeLayer属于Core Animation框架,走GPU,动画渲染直接提交给手机GPU.

    

     drawRect是UIView的方法,重写此方法可以完成绘制图形功能

 

第一步: //创建路径

        let linePath = UIBezierPath()

        //起点

        linePath.move(to: CGPoint.init(x: 30, y: 30))

        //添加其他点

        linePath.addLine(to: CGPoint.init(x: 150, y: 150))

        linePath.addLine(to: CGPoint.init(x: 180, y: 20))

        //闭合路径

        linePath.close()

        

   第二部:     //设施路径画布

        let lineShape = CAShapeLayer()

        lineShape.frame = CGRect.init(x: 10, y: 10, width: 350, height: 400)

        //宽度

        lineShape.lineWidth = 2

        //线条之间点的样式

        lineShape.lineJoin = kCALineJoinMiter

        //线条结尾的样式

        lineShape.lineCap = kCALineCapSquare

        //路径颜色

        lineShape.strokeColor = UIColor.red.cgColor

        //获取贝塞尔曲线的路径------设置画布的路径

        lineShape.path = linePath.cgPath

        //填充色

        lineShape.fillColor = UIColor.clear.cgColor

     第三步:   //把绘制的图放到layer上

        self.layer.addSublayer(lineShape)

        

===========多条路径合并=====

 

  //多条路径合并

        let bz1 = UIBezierPath.init()

      bz1.move(to: CGPoint.init(x: 10, y: 10))

        bz1.addLine(to: CGPoint.init(x: 100, y: 10))

        bz1.stroke()

        let bz2 = UIBezierPath.init()

       bz2.move(to: CGPoint.init(x: 10, y: 100))

        bz2.addLine(to: CGPoint.init(x: 100, y: 200))

        bz2.stroke()

        bz1.append(bz2)//多条路径合并

 

============给cashaperlayer添加动画(绘制时候有动画效果)=

 

 

 //CAShapeLayer,可以看做一个动画容器。把UIBezierPath绘制的路径放进去,点就会沿着这路径前进,加上颜色、动画等渲染后显示在界面上

        let bz1 = UIBezierPath.init()

        bz1.move(to: CGPoint.init(x: 10, y: 10))

        bz1.addLine(to: CGPoint.init(x: 100, y: 10))

        

        let shapeLayer = CAShapeLayer()

        shapeLayer.path = bz1.cgPath //存入UIBezierPath的路径

        shapeLayer.fillColor = UIColor.red.cgColor //设置填充色

        shapeLayer.lineWidth = 2  //设置路径线的宽度

        shapeLayer.strokeColor = UIColor.gray.cgColor //路径颜色

        //如果想变为虚线设置这个属性,[实线宽度,虚线宽度],若两宽度相等可以简写为[宽度]

        shapeLayer.lineDashPattern = [2]

        //一般可以填"path"  "strokeStart" "strokeEnd"  。。。。。。

        let baseAnimation = CABasicAnimation(keyPath: "strokeEnd")

        baseAnimation.duration = 2   //持续时间

        baseAnimation.fromValue = 0  //开始值

        baseAnimation.toValue = 2    //结束值

        baseAnimation.repeatDuration = 5  //重复次数

    shapeLayer.add(baseAnimation, forKey: nil) //给ShapeLayer添加动画

        //显示在界面上

        self.layer.addSublayer(shapeLayer)

 

1.********简易绘图*******

/**
 绘图https://www.jianshu.com/p/1e4bc8378c36
 */

import UIKit

class LYBDrawView: UIView {

    override func draw(_ rect: CGRect) {
        //绘制椭圆,宽和高一样的时候就是正圆
//        //1.UIKit方式绘制
//        let p = UIBezierPath(ovalIn: CGRect.init(x: 0, y: 0, width: 100, height: 50))
//        UIColor.blue.setFill()
//        p.fill()

//        //2.Core Graphic/QuartZ 2D方式绘制,(还有一种OpenGL ES)iOS用不着
//        let ctx = UIGraphicsGetCurrentContext()!
//        ctx.addEllipse(in: CGRect.init(x: 0, y: 0, width: 100, height: 50))
//        ctx.setFillColor(UIColor.blue.cgColor)
//        ctx.fillPath()

//        //4.从上下文中获取图片
//        UIGraphicsBeginImageContextWithOptions(CGSize.init(width: 100, height: 100), false, 0)
//        let p = UIBezierPath.init(ovalIn:  CGRect.init(x: 0, y: 0, width: 100, height: 50))
//        UIColor.blue.setFill()
//        p.fill()
//        let image = UIGraphicsGetImageFromCurrentImageContext()
//        UIGraphicsEndImageContext()
        
        //
    }
    
    
//     // 3. 在UIView子类的drawLayer:inContext:方法中,使用下面的方法,draw方法还必须实现
//    override func draw(_ layer: CALayer, in ctx: CGContext) {
//        //方法3,
////        UIGraphicsPushContext(ctx) //将ctx设置为当前context
////        let p = UIBezierPath.init(ovalIn:  CGRect.init(x: 0, y: 0, width: 100, height: 50))
////        UIColor.red.setFill()
////        p.fill()
////        UIGraphicsPushContext(ctx)
//
//
//
//
//    }
   
    
    

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值