iOS绘图-UIBezierPath的使用

UIBezierPath简单介绍

    iOS系统本身提供了两套绘图的框架,即UIBezierPath 和 Core Graphics。使用UIBezierPath可以创建基于矢量的路径,此类是Core Graphics框架关于路径的封装,所以使用起来比较简单。使用此类可以定义简单的形状,如椭圆、矩形或者有多个直线和曲线段组成的形状等。UIBezierPath是CGPathRef数据类型的封装。如果是基于矢量形状的路径,都用直线和曲线去创建。我们使用直线段去创建矩形和多边形,使用曲线去创建圆弧(arc)、圆或者其他复杂的曲线形状。

    使用UIBezierPath,你只能在当前上下文中绘图,所以如果你当前处于UIGraphicsBeginImageContextWithOptions函数或drawRect:方法中,你就可以直接使用UIKit提供的方法进行绘图。我们一般使用UIBezierPath都是在重写的drawRect方法中实现。首先我们看UIBezierPath绘图的基本步骤:
  1. 重写drawRect方法,但不需要我们自己获取当前上下文
  2. 创建Bezier path对象并设置绘图相关属性
  3. 添加线或者曲线定义路径
  4. 渲染,完成绘制

UIBezierPath创建方法

UIBezierPath类提供了下面这些类方法创建路径:

+ (instancetype)bezierPath;
+ (instancetype)bezierPathWithRect:(CGRect)rect;
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; 
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;
+ (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;
下面我们一个一个的简单介绍其用法:
    + (instancetype)bezierPath;
这个方法适用的范围比较广,适用此方法我们可以根据我们的的需要画出任意的图形。
    + (instancetype)bezierPathWithRect:(CGRect)rect;
这个方法根据传入的Rect参数画出一个矩形
    + (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
这个方法根据一个矩形画内切的曲线,一般我们用它来画圆或者椭圆
    + (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; 
    + (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;
这两个方法比较类似,两个类方法都可以画带有圆角的矩形,第一个参数是矩形,第二个参数是圆角大小,但是第二个方法可以指定把矩形某一个角画成圆角。
    + (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;
这个方法用于画弧线,center:弧线中心点的坐标 radius:弧线所在圆的半径 startAngle:弧线开始的角度 endAngle:弧线结束的角度 clockwise: 是否顺时针画弧线(YES表示顺时针 NO表示逆时针)

下面通过几段代码做个事例(注意下面代码都在- (void)drawRect:(CGRect)rect方法中实现)

画三角形

//绘制三角形
- (void)drawTriangle{
    //1. 创建UIBezierPath对象
    UIBezierPath *path = [UIBezierPath bezierPath];

    //2. 配置属性
    [[UIColor yellowColor] setFill];    //设置填充颜色
    [[UIColor redColor] setStroke];     //设置描边颜色
    path.lineWidth = 3;     //设置线宽

    //3.添加路径
    [path moveToPoint:CGPointMake(160, 100)];
    [path addLineToPoint:CGPointMake(100, 220)];
    [path addLineToPoint:CGPointMake(220, 220)];

    [path closePath];   //闭合路径(也可通过-addLineToPoint:方法添加)

    //4.渲染,完成绘制
    [path stroke];
    [path fill];
}

效果图:
iOS绘图-UIBezierPath的使用_第1张图片

画矩形

//矩形
- (void)drawRectPath {
    //1. 创建UIBezierPath对象并指定路径
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(60, 100, 200, 100)];

    //2. 配置属性
    [[UIColor yellowColor] setFill];    //设置填充颜色
    [[UIColor redColor] setStroke];     //设置描边颜色

    path.lineWidth = 3;     //设置线宽

    /*
        设置线条拐角样式
        typedef CF_ENUM(int32_t, CGLineCap) {
        kCGLineCapButt,     //默认
        kCGLineCapRound,    //圆角
        kCGLineCapSquare    //方形
        };
     */
    path.lineCapStyle = kCGLineCapRound;

    /*
        两条线连结点的样式
        typedef CF_ENUM(int32_t, CGLineJoin) {
        kCGLineJoinMiter,   //默认:斜接
        kCGLineJoinRound,   //圆滑衔接
        kCGLineJoinBevel    //圆滑衔接
        };
     */
    path.lineJoinStyle = kCGLineJoinBevel;  

    //3. 渲染,完成绘制
    [path stroke];
    [path fill];
}

效果图:
iOS绘图-UIBezierPath的使用_第2张图片
画椭圆(圆)

//椭圆
- (void)drawCiclePath {
    // 当传入参数为正方形时,绘制出的内切图形就是圆,为矩形时画出的就是椭圆
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(60, 100, 200,300)];

    //配置属性
    [[UIColor yellowColor] setFill];    //设置填充颜色
    [[UIColor redColor] setStroke];     //设置描边颜色

    path.lineWidth = 3;     //设置线宽

    //渲染
    [path stroke];
    [path fill];
}

效果图:

画带有圆角的矩形

- (void)drawRoundedRectPath {

    //创建带圆角的矩形 圆角半径:20
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(60, 100, 200, 200) cornerRadius:20];

    //创建可以指定圆角位置的矩形
    //第一个参数一样是传了个矩形
    //第二个参数是指定在哪个方向画圆角
    //第三个参数是一个CGSize类型,用来指定水平和垂直方向的半径的大小
    //UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(60, 100, 200, 200) byRoundingCorners:UIRectCornerTopLeft cornerRadii:CGSizeMake(20, 20)];

    //配置属性
    [[UIColor yellowColor] setFill];    //设置填充颜色
    [[UIColor redColor] setStroke];     //设置描边颜色

    path.lineWidth = 3;     //设置线宽

    //渲染
    [path stroke];
    [path fill];
}

效果图:
iOS绘图-UIBezierPath的使用_第3张图片

画弧线

使用UIBeizerPath画弧线我们需要了解画弧线的参考系:
iOS绘图-UIBezierPath的使用_第4张图片

//画弧线
- (void)drawARCPath {
 //CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; 角度转弧度

    CGPoint center = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2);

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:DegreesToRadians(100) clockwise:YES];

    path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinRound;
    path.lineWidth = 5.0;

    UIColor *strokeColor = [UIColor redColor];
    [strokeColor set];

    [path stroke];
}

iOS绘图-UIBezierPath的使用_第5张图片

我们要明确一点,画弧参数startAngle和endAngle使用的是弧度,而不是角度,因此我们需要将常用的角度转换成弧度。对于效果图中,我们设置弧的中心为控件的中心,起点弧度为0,也就是正东方向,而终点是135度角的位置。如果设置的clockwise:YES是逆时针方向绘制,如果设置为NO,效果如下:

iOS绘图-UIBezierPath的使用_第6张图片

画二次贝塞尔曲线

说到画二次贝塞尔曲线那就必须要说控制点了,首先我们看下面的图片:

iOS绘图-UIBezierPath的使用_第7张图片
画二次贝塞尔曲线我们用下面的方法实现:

- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;

参数说明:

endPoint:终端点
controlPoint:控制点,对于二次贝塞尔曲线,只有一个控制点

- (void)drawSecondBezierPath {

    // 创建路径对象
    UIBezierPath *path = [UIBezierPath bezierPath];

    // 设置起始点,终点和控制点的位置
    CGPoint startPoint = CGPointMake(20, 200);
    CGPoint endPoint = CGPointMake(300, 200);
    CGPoint controlPoint = CGPointMake(100, 400);

    // 设置起始点位置
    [path moveToPoint:startPoint];

    // 添加二次曲线
    [path addQuadCurveToPoint:endPoint controlPoint:controlPoint];

    path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinRound;
    path.lineWidth = 5.0;

    UIColor *strokeColor = [UIColor redColor];
    [strokeColor set];

    [path stroke];
}

效果图:

画三次贝塞尔曲线

贝塞尔曲线必定通过首尾两个点,称为端点;中间两个点虽然未必要通过,但却起到牵制曲线形状路径的作用,称作控制点。关于三次贝塞尔曲线的控制器,看下图:

iOS绘图-UIBezierPath的使用_第8张图片

如下方法就是画三次贝塞尔曲线的关键方法,以三个点画一段曲线,一般和-moveToPoint:配合使用。
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;

实现代码:

//画三次塞贝尔曲线
- (void)drawThirdBezierPath { UIBezierPath *path = [UIBezierPath bezierPath]; // 设置起始端点 [path moveToPoint:CGPointMake(20, 150)]; [path addCurveToPoint:CGPointMake(300, 150) controlPoint1:CGPointMake(160, 0) controlPoint2:CGPointMake(160, 250)]; path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinRound;
    path.lineWidth = 5.0;

    UIColor *strokeColor = [UIColor redColor];
    [strokeColor set];

    [path stroke];
}

效果图:

我们可以通过两个控制点的坐标控制曲线的弯曲度,如果两个控制点的纵坐标和两个端点在同一水平线上,那么画出的就是一条直线了。

源代码在我的github网站(https://github.com/cokeduo/UIBezierPath-)有需要的小伙伴可以下载。

你可能感兴趣的:(ios,画图,二次贝塞尔曲线,画图框架,三次贝塞尔曲线)