UIBezierPath的使用

最近研究了下UIBezierPath,虽然他的构造方法不是特别多,但是感觉还是特别实用的,就是用起来感觉很方便,其主要作用还是用于为视图的Layer层添加路径,相当于根据我们创建的path来对目标视图进行切割.比如说我要把一个视图的形状裁剪一下,或者我想自定义一个几何图形什么的,用UIBezierPath来实现都是很方便的.唯一不方便的地方就是如果要在一个view上只使用UIBezierPath来进行绘制几何图形的话,那么必须要在- (void)drawRect:(CGRect)rect方法里绘制或者调用,这样一来就给我们带来了些许的限制,所以,在日常的开发中,如果要创建自定义的几何图形的话,经常还是使用CAShapeLayer和UIBezierPath共同来创建.各位看官可以看下我的这篇博客:CAShapeLayer的使用,希望能给各位大人带来少许帮助.

不过,今天我们就事论事,只说UIBezierPath的使用,下面是我写的一个Demo,可以先看下效果

这个Demo里包括了UIBezierPath使用频率最高的几种几何图形以及创建的方法,其实UIBezierPath的使用很简单,只不过有些细节需要注意下,下面就先看一下UIBezierPath提供的构造方法(因为对UIBezierPath对象的设置很多地方都是雷同的,所以第一个构造方法我会详细讲解使用方法,后面的几个就不详细讲解了,该Demo我已经上传到github,各位看官可以去github下载完整的工程代码,包括了使用实例,链接我会在后面贴出来): 
- +(instancetype)bezierPath; 
该方法直接返回一个UIBezierPath对象,不需要传递任何参数,我们可以直接对创建出来的对象操作,使用方法如下:

//绘制一个三角形
-(void)drawtriangle{
    //绘制一条完整路径  首先创建路径对象,接着按绘制顺序添加关键点,最后调用[path closePath]方法闭合路径
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(40, self.frame.size.height - 40)];
    [path addLineToPoint:CGPointMake(k_ScreenWidth - 40, self.frame.size.height - 40)];
    [path addLineToPoint:CGPointMake(k_ScreenWidth/2, 40)];
    [path closePath];

    /*设置填充颜色   创建一个颜色对象之后,需要调用颜色的set方法设置上下文环境,接着调用路径的fill方法使用上下文环境中的颜色来填充
    Tip: 这个fill方法很有意思
         如果第一次设置上下文环境为红色,那么调用fill的则会为该路径内填充红色
         但是第二次设置上下文环境为绿色时,调用fill方法并不是说将路径内的红色替换掉,而是在红色的上方填充一次绿色
         我会在博客里验证,读者也可自行验证
    */
    UIColor *redColor = [UIColor redColor];
    [redColor set];
    [path fill];

    //设置线条属性  各种格式我会贴出来给大家看,方便对比
    path.lineCapStyle = kCGLineJoinRound;  //线段端点格式
    path.lineJoinStyle = kCGLineJoinRound; //线段接头格式
    path.lineWidth = 8;

    //设置路径颜色  原理和设置填充颜色一样,这不过是调用[path stroke]方法来设置路径额颜色 设置线宽为8
    UIColor *blackColor = [UIColor blackColor];
    [blackColor set];
    [path stroke];
}
  • 上文提到了lineCapStyle和lineJoinStyle,这两个属性分别对应的是线条端点的风格和线条接头处的风格,有以下三个枚举值:
typedef CF_ENUM(int32_t, CGLineJoin) {
    kCGLineJoinMiter,
    kCGLineJoinRound,
    kCGLineJoinBevel
};

对应的风格如下所示:

端点处的风格:(lineCapStyle)
kCGLineJoinMiter,
kCGLineJoinBevel  这两个风格是一样的,都是直角风格如下所示:

kCGLineJoinRound,圆角风格,如下所示:

接头处的风格:(lineJoinStyle)

kCGLineJoinMiter  斜接

 kCGLineJoinRound  圆角

kCGLineJoinBevel  斜角

 
- +(instancetype)bezierPathWithRect:(CGRect)rect; 
该方法会根据传进去的CGRect结构体来创建一个矩形

  • +(instancetype)bezierPathWithOvalInRect:(CGRect)rect; 
    该方法会根据传进去的结构体(矩形)创建一个内切圆,如果该矩形是正方形的话,那么切出来的是一个圆形,如果是长方形的话,切出来的则是一个椭圆
  • +(instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; 
    该方法会根据传进去的矩形和圆角角度创建一个四个角都是圆角的矩形
  • +(instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii; 
    参数解析: 
    rect: 基础矩形 
    corners: 选择矩形中需要添加圆角的位置,该值有四个枚举值,如下所示: 
    UIRectCornerTopLeft 左上方添加 
    UIRectCornerTopRight 右上方添加 
    UIRectCornerBottomLeft 左下方添加 
    UIRectCornerBottomRight 右下方添加 
    UIRectCornerAllCorners 全部添加 
    传值的时候,可以传进去单独的值,如:UIRectCornerTopLeft(在左上角添加圆角),可以传进去多个值,中间使用’|’隔开,如:UIRectCornerTopLeft|UIRectCornerTopRight(给左上角和右上角添加圆角) 
    ornerRadii:这个参数的意思是,传进去一个矩形A的宽高,以需要添加的角的顶点为矩形A的左上角,在该矩形内做内切圆,为矩形添加圆角.
  • +(instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise; 
    该方法是用来绘制圆形的 
    参数解析: 
    center 圆心位置 
    radius 半径 
    startAngle 开始角度,默认从3点钟开始 
    endAngle 结束角度 
    clockwise 是否顺时针方向绘制
  • +(instancetype)bezierPathWithCGPath:(CGPathRef)CGPath; 
    该方法和第一个方法类型类似,只不过该方法传进去的是一个CGPath的路径.
  • 关于fill的讨论 
    上文中提到, 
    Tip: 这个fill方法很有意思 
    如果第一次设置上下文环境为红色,那么调用fill的则会为该路径内填充红色 
    但是第二次设置上下文环境为绿色时,调用fill方法并不是说将路径内的红色替换掉,而是在红色的上方填充一次绿色 
    现在我们就来验证一下这个说法,首先,我们绘制一个圆形,代码如下,填充颜色为红色,边框颜色为黑色,线宽30:
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(40, 80, k_ScreenWidth - 80, k_ScreenWidth - 80)];
    //设置填充颜色
    UIColor *redColor = [UIColor redColor];
    [redColor set];
    [path fill];

    //设置路径格式
    path.lineWidth = 30.0;
    path.lineCapStyle = kCGLineJoinRound;
    path.lineJoinStyle = kCGLineJoinRound;

    //设置路径颜色
    UIColor *blackColor = [UIColor blackColor];
    [blackColor set];
    [path stroke];

效果如下:

然后我们在末尾再次填充颜色,执行代码如下:

 UIColor *greenColor = [UIColor greenColor];
    [greenColor set];
    [path fill];
  • 效果如下所示:

我们很清楚的可以看出来,边框的宽度减少了一半,原因就是当我们再次调用fill方法的时候,该方法是在原有图层上又添加了一层图像.由于路径的绘制原则是向内外扩展,我们设置的路径宽度是30,那么它就会向内扩展15向外扩展15.当我们再次绘制图层的时候,由于是在原来的基础上填充的,那么就会将向内扩展的15个单位的路径覆盖上,就导致了我们看到路径宽度比原来减少了一半的效果.

//绘制一个三角形  该方法会详细讲述各个参数的意思及使用方法,后面的方法仅仅展示使用方法
-(void)drawtriangle{
    //绘制一条完整路径  首先创建路径对象,接着按绘制顺序添加关键点,最后调用[path closePath]方法闭合路径
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(40, self.frame.size.height - 40)];
    [path addLineToPoint:CGPointMake(k_ScreenWidth - 40, self.frame.size.height - 40)];
    [path addLineToPoint:CGPointMake(k_ScreenWidth/2, 40)];
    [path closePath];

    /*设置填充颜色   创建一个颜色对象之后,需要调用颜色的set方法设置上下文环境,接着调用路径的fill方法使用上下文环境中的颜色来填充
    Tip: 这个fill方法很有意思
         如果第一次设置上下文环境为红色,那么调用fill的则会为该路径内填充红色
         但是第二次设置上下文环境为绿色时,调用fill方法并不是说将路径内的红色替换掉,而是在红色的上方填充一次绿色
         我会在博客里验证,读者也可自行验证
    */
    UIColor *redColor = [UIColor redColor];
    [redColor set];
    [path fill];

    //设置线条属性
    path.lineCapStyle = kCGLineJoinRound;  //线段端点格式
    path.lineJoinStyle = kCGLineJoinRound; //线段接头格式
    path.lineWidth = 8;

    //设置路径颜色  原理和设置填充颜色一样,这不过是调用[path stroke]方法来设置路径额颜色 设置线宽为8
    UIColor *blackColor = [UIColor blackColor];
    [blackColor set];
    [path stroke];
}

#pragma mark:由于设置填充颜色、线条颜色、线条宽度代码重复冗余,所以将其写到一个方法里,统一设置为填充颜色为红色,线条颜色为黑色,线条宽度为8
//绘制一个矩形
-(void)drawRectangle{
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(40,40 ,k_CurrentWidth - 80 , k_CurrentHeight - 80)];
    [self setPath:path];
}

//绘制一个实心圆形
-(void)drawFillCircle{
    /*
      该方法是使用一个矩形为基准绘制其内切圆
      当该矩形是正方形时,绘制出的为圆形
      当该矩形为长方形的时候,绘制出来的是椭圆
     */
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(40, 80, k_ScreenWidth - 80, k_ScreenWidth - 80)];
    [self setPath:path];
}

//绘制一个空心圆形  主要为了展示使用不同的工厂方法来创建圆形
-(void)drawEmptyCircle{
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(k_ScreenWidth/2, k_CurrentHeight - 300) radius:(k_ScreenWidth - 40)/2
                                                    startAngle:0
                                                      endAngle:k_DegreesToRadians(360)
                                                     clockwise:YES];
    //设置填充颜色
    UIColor *redColor = [UIColor clearColor];
    [redColor set];
    [path fill];

    //设置路径格式
    path.lineWidth = 8;
    path.lineCapStyle = kCGLineJoinRound;
    path.lineJoinStyle = kCGLineJoinRound;

    //设置路径颜色
    UIColor *blackColor = [UIColor blackColor];
    [blackColor set];
    [path stroke];
}

//绘制一个四个角都是圆角额矩形
-(void)drawCornerRectangle{
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(40,40 ,k_CurrentWidth - 80 , k_CurrentHeight - 80)
                                                    cornerRadius:20];
    [self setPath:path];
}

//绘制一个可选角度的矩形
-(void)drawRectWithLeftAndRightCorner{
    /*
     参数解析:
     bezierPathWithRoundedRect   绘制矩形的大小
     byRoundingCorners           有哪几个角需要绘制
     cornerRadii                 圆角角度,使用角的顶点作为圆心来切圆角
     */
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(40,40 ,k_CurrentWidth - 80 , k_CurrentHeight - 80)
                                               byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight
                                                     cornerRadii:CGSizeMake((k_CurrentWidth - 80)/2, (k_CurrentWidth - 80)/2)];
    [self setPath:path];
}

- (void)drawSecondBezierPath {
    UIBezierPath *path = [UIBezierPath bezierPath];
    //设置一个起始点
    [path moveToPoint:CGPointMake(20, self.frame.size.height - 100)];
    // 添加二次曲线
    [path addQuadCurveToPoint:CGPointMake(self.frame.size.width - 20, self.frame.size.height - 100)
                 controlPoint:CGPointMake(self.frame.size.width / 2, 0)];

    path.lineCapStyle = kCGLineJoinBevel;
    path.lineJoinStyle = kCGLineJoinRound;
    path.lineWidth = 8.0;

    UIColor *strokeColor = [UIColor blackColor];
    [strokeColor set];
    [path stroke];
}

- (void)drawThirdBezierPath {
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(20, 200)];

    [path addCurveToPoint:CGPointMake(300, 200)
            controlPoint1:CGPointMake(160, 50)
            controlPoint2:CGPointMake(160, 300)];

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

    UIColor *strokeColor = [UIColor blackColor];
    [strokeColor set];
    [path stroke];
}

-(void)setPath:(UIBezierPath*)path{
    //设置填充颜色
    UIColor *redColor = [UIColor redColor];
    [redColor set];
    [path fill];

    //设置路径格式
    path.lineWidth = 8.0;
    path.lineCapStyle = kCGLineJoinRound;
    path.lineJoinStyle = kCGLineJoinRound;

    //设置路径颜色
    UIColor *blackColor = [UIColor blackColor];
    [blackColor set];
    [path stroke];
} 
时间: 2024-10-24 22:38:34

UIBezierPath的使用的相关文章

CALayer与UIBezierPath

UIView继承于UIResponder CALayer继承于nsobject 创建UIView创建一个layer,通过UIView的layer属性可依访问它的图层.UIView具有事件处理功能,可以与用户交互,layer负责显示和动画任务. 要显示一个UIView,会自动调用起drawRect方法绘画所有内容,然后字啊将图层拷贝到屏幕上,完成UICView的显示. frame不能作动画  修改大小bounds  修改位子position CALayer不能直接使用UIColer.UIImage

IOS Animation-CAShapeLayer、UIBezierPath与Animation的结合

在阅读本文之前,对CAShapeLayer.UIBezierPath不熟悉的话,可以先阅读文章 贝塞尔曲线与Layer 如果对动画不熟悉的话,先阅读文章 动画基础.深入 Layer是绘图的画板,Bezier是画图的画笔,Animation是画图的动作.现在我们可以通过下面例子更好的让它们更好地结合在一起. 1)画一个小屋子动画 我们首先通过定义CAShapeLayer画板,然后定义path来确定画图路径.最后使用动画.如下面代码 1 //让一个屋子的线画起来的动画效果 2 func addCAS

UIBezierPath 贝塞尔曲线

1. UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(30, 30, 100, 100) cornerRadius:0]; CAShapeLayer * layer = [CAShapeLayer layer];    layer.path = path.CGPath;    layer.fillColor = [[UIColor blackColor]CGColor]; layer.strokeC

使用贝赛尔路径(UIBezierPath)创建画板

在iOS开发中,创建图形,经常会使用贝塞尔路径,用于描绘一些比较复杂的图形. 使用贝塞尔路径,需要在view中的方法- (void)drawRect:(CGRect)rect中进行描绘. 1 - (void)drawRect:(CGRect)rect{ 2 UIBezierPath *path = [UIBezierPath bezierPath]; 3 // 起点 4 [path moveToPoint:CGPointMake(0, 0)]; 5 // 途经点 6 [path addLineT

通过UIBezierPath贝塞尔曲线画圆形、椭圆、矩形

/**创建椭圆形的贝塞尔曲线*/ UIBezierPath *_ovalPath=[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 100)]; /**创建矩形的贝塞尔曲线*/ UIBezierPath *_rectPath=[UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 200, 100)]; /**创建圆形的贝塞尔曲线*/ UIBezierPath *_circlePa

UIBezierPath和CGContext类中的方法

 UIBezierPath和CGContext类中的方法 CGContextSetLineWidth(ctr, 10); // 即描写边线又填充 CGContextDrawPath(ctr, kCGPathFillStroke); void CGContextSetLineWidth(CGContextRef c, CGFloat width); // 设置边线的宽度 void CGContextAddLineToPoint(CGContextRef c, CGFloat x, CGFloat

iOS学习:CAShapeLayer与UIBezierPath动画

CAShapeLayer与UIBezierPath动画: CAShapeLayer与UIBezierPath的动画,就离不开 CABasicAnimation:也将会使用到 strokeEnd.strokeStart.lineWidth 三个属性: 先做一条贝塞尔曲线: UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(40, 80)]; [path addCurveToPoint:CGPo

iOS开发 贝塞尔曲线UIBezierPath(2)

使用CAShapeLayer与UIBezierPath可以实现不在view的drawRect方法中就画出一些想要的图形 . 1:UIBezierPath: UIBezierPath是在 UIKit 中的一个类,继承于NSObject,可以创建基于矢量的路径.此类是Core Graphics框架关于path的一个OC封装.使用此类可以定义常见的圆形.多边形等形状 .我们使用直线.弧(arc)来创建复杂的曲线形状.每一个直线段或者曲线段的结束的地方是下一个的开始的地方.每一个连接的直线或者曲线段的集

用UIBezierPath数组对UIView进行镂空处理

效果 源码 // // CutOutClearView.h // CutOutMaskView // // Created by YouXianMing on 16/7/8. // Copyright © 2016年 YouXianMing. All rights reserved. // #import <UIKit/UIKit.h> @interface CutOutClearView : UIView @property (nonatomic, strong) UIColor *fill

XMG UIBezierPath与CGContextRef

1. 贝泽尔路径只有当stroke的时候才会添加到上下文当中 如果想要在stroke之前就添加到上下文中的话 // 把路径添加到上下文 // .CGPath 可以UIkit的路径转换成CoreGraphics路径 CGContextAddPath(ctx, path.CGPath); 如果用贝泽尔stroke 的话只认贝泽尔的状态,是不去管上下文的状态 2. 现在存在的问题是如果我设置的是上下文的状态的话.那么以后绘制的内容所有的状态都和现在一样. 我还需要去单独进行设置 3. 绘图的状态包括线