iOS BeizierPath 绘图

牧云@^-^@ 提交于 2020-03-02 06:18:10

iOS BeizierPath 绘图

    最近工作,因为是一款理财的产品,所以进度条改成圆,当然也参考了几篇优秀的博文,稍后一一罗列,下面简单介绍:使用UIBezierPath类可以创建基于矢量的路径,这个类在UIKit中。此类是Core Graphics框架关于path的一个封装。使用此类可以定义简单的形状,如椭圆或者矩形,或者有多个直线和曲线段组成的形状。

Bezier Path 基础                                            

    UIBezierPath对象是CGPathRef数据类型的封装。path如果是基于矢量形状的,都用直线和曲线段去创建。                  我们使用直线段去创建矩形和多边形,使用曲线段去创建弧(arc),圆或者其他复杂的曲线形状。每一段都包括一个或者多个点,绘图命令定义如何去诠释这些点。每一个直线段或者曲线段的结束的地方是下一个的开始的地方。每一个连接的直线或者曲线段的集 合成为subpath。一个UIBezierPath对象定义一个完整的路径包括一个或者多个subpaths。                               

创建和使用一个path对象的过程是分开的。创建path是第一步,包含一下步骤:                      

(1)创建一个Bezier path对象。                      

(2)使用方法moveToPoint:去设置初始线段的起点。                      

(3)添加line或者curve去定义一个或者多个subpaths。                      

(4)改变UIBezierPath对象跟绘图相关的属性。  

    当创建path,我们应该管理path上面的点相对于原点(0,0),这样我们在随后就可以很容易的移动path了。为了绘制path对象, 我们要用到stroke和fill方法。这些方法在current graphic context下渲染path的line和curve段。  

   下面我们用贝塞尔曲线画一个多边形

-(void)drawRect:(CGRect)rect
{
    
    UIColor *color = [UIColor yellowColor];
    [color set];  //设置线条颜色
    
    UIBezierPath* aPath = [UIBezierPath bezierPath];
    
    aPath.lineWidth = 10.0;//设置线条的粗细
    
    aPath.lineCapStyle = kCGLineCapRound;  //线条拐角
    aPath.lineJoinStyle = kCGLineCapRound;  //终点处理
    
    // 设置多边形最开始的点
    [aPath moveToPoint:CGPointMake(100.0, 0.0)];
    
    // 画相应的线条
    [aPath addLineToPoint:CGPointMake(200.0, 40.0)];
    [aPath addLineToPoint:CGPointMake(160, 140)];
    [aPath addLineToPoint:CGPointMake(40.0, 140)];
    [aPath addLineToPoint:CGPointMake(0.0, 40.0)];
    [aPath closePath]; //第五条线通过调用closePath方法得到的
    
    [aPath stroke]; //Draws line 根据坐标点连线  //填充线条
   // [aPath fill];//图形内部填充
    
}

              

绘制圆

用到这个方法                      

+ (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect ;

当传入的 rect 是一个正方形时,则绘制一个圆,如果是矩形时,则是椭圆

创建一段弧的方法

+ (UIBezierPath *)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL )clockwise;

参数介绍:

center:圆弧的中心

radius:半径

startAngle:开始角度

endAngle:结束角度

clockwise:是否顺时针方向


画一段弧形的相关代码

  1. #import "DrawPolygonView.h"
    
    #define pi 3.14159265359
    #define   DEGREES_TO_RADIANS(degrees)  ((pi * degrees)/ 180)
    
    @implementation DrawPolygonView
    
    -(void)drawRect:(CGRect)rect
    {
    
        UIColor *color = [UIColor redColor];
        [color set];  //设置线条颜色
    
        UIBezierPath* aPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150)
                                                             radius:75
                                                         startAngle:0
                                                           endAngle:DEGREES_TO_RADIANS(135)
                                                          clockwise:YES];
    
        aPath.lineWidth = 5.0;
        aPath.lineCapStyle = kCGLineCapRound;  //线条拐角
        aPath.lineJoinStyle = kCGLineCapRound;  //终点处理
        [aPath stroke];
    
    }


同样,用上述方法可以绘制圆,但是这个方法有弊端,会大量占用 cpu, 导致效率不佳,而我们可以用下面这个方法绘制出高性能的圆,主要是不占用系统 cpu, 那么我们在哪里绘制,其实是用 GPU处理,这样会大大提高运行速度,当然最主要的是不占用 cpu,至于为什么会这样?首先下面介绍的是用CAShapeLayer和贝塞尔曲线绘制.

CAShapeLayer和DrawRect的比较
DrawRect:DrawRect属于CoreGraphic框架,占用CPU,消耗性能大
CAShapeLayer:CAShapeLayer属于CoreAnimation框架,通过GPU来渲染图形,节省性能。动画渲染直接提交给手机GPU,不消耗内存

贝塞尔曲线与CAShapeLayer的关系
1,CAShapeLayer中shape代表形状的意思,所以需要形状才能生效
2,贝塞尔曲线可以创建基于矢量的路径
3,贝塞尔曲线给CAShapeLayer提供路径,CAShapeLayer在提供的路径中进行渲染。路径会闭环,所以绘制出了Shape
4,用于CAShapeLayer的贝塞尔曲线作为Path,其path是一个首尾相接的闭环的曲线,即使该贝塞尔曲线不是一个闭环的曲线

用 CAShapeLayer 和 UIBeizierPath 绘制圆或者圆弧

-(void)drawCircleOnView
{
    //创建出CAShapeLayer
    self.shapeLayer = [CAShapeLayer layer];
    self.shapeLayer.frame = CGRectMake(0, 0, 200, 200);//设置shapeLayer的尺寸和位置
    self.shapeLayer.position = self.view.center;
    self.shapeLayer.fillColor = [UIColor clearColor].CGColor;//填充颜色为ClearColor
    
    //设置线条的宽度和颜色
    self.shapeLayer.lineWidth = 1.0f;
    self.shapeLayer.strokeColor = [UIColor redColor].CGColor;
    
    //创建出圆形贝塞尔曲线
    UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 200)];
    
    //让贝塞尔曲线与CAShapeLayer产生联系
    self.shapeLayer.path = circlePath.CGPath;
    
    //添加并显示
    [self.view.layer addSublayer:self.shapeLayer];
}

如果要做一个圆形进度条,那么我们需要对这两个参数进行设置

strokeEnd和strokeStart
Stroke:用笔画的意思
在这里就是起始笔和结束笔的位置
Stroke为1的话就是一整圈

然后将其加入到 NSTimer 中做一些相应的处理就可以实现动态绘制圆了,大家赶紧试试吧.


参考博客地址:http://blog.it985.com/7654.html




易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!