iOS UIBezierPath贝塞尔曲线常用方法
chrissy740
8年前
<p><strong>关于 UIBezierPath</strong></p> <p>UIBezierPath 这个类在UIKit中, 是Core Graphics框架关于path的一个封装,使用此类可以定义简单的形状,比如我们常用到,矩形,圆形,椭圆,弧,或者不规则的多边形</p> <p><strong>UIBezierPath 基本使用方法</strong></p> <p>UIBezierPath 对象是CGPathRef数据类型的封装。path如果是基于矢量形状的,都用直线或曲线去创建。我们一般使用 UIBezierPath 都是在重写view的 drawRect 方法这种情形。我们用直线去创建矩形或多边形,使用曲线创建弧或者圆。创建和使用path对象步骤:</p> <p>1、 重写View的 drawRect 方法</p> <p>2、 创建 UIBezierPath 的对象</p> <p>3、 使用方法 moveToPoint: 设置初始点</p> <p>4、 根据具体要求使用 UIBezierPath 类方法绘图(比如要画线、矩形、圆、弧?等)</p> <p>5、 设置 UIBezierPath 对象相关属性 (比如 lineWidth 、 lineJoinStyle 、 aPath.lineCapStyle 、 color )</p> <p>6、 使用stroke 或者 fill方法结束绘图</p> <p>比如我们想要画一条线demo:</p> <pre> - (void)drawRect:(CGRect)rect { UIColor *color = [UIColor redColor]; [color set]; //设置线条颜色 UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(10, 10)]; [path addLineToPoint:CGPointMake(200, 80)]; path.lineWidth = 5.0; path.lineCapStyle = kCGLineCapRound; //线条拐角 path.lineJoinStyle = kCGLineJoinRound; //终点处理 [path stroke]; }</pre> <p><strong>其他基本使用方法</strong></p> <p>在介绍其他使用方法之前,我们先来看一下 path 的几个属性,以便下面我进行设置。</p> <p>1、 [color set]; 设置线条颜色,也就是相当于画笔颜色</p> <p>2、 path.lineWidth = 5.0; 这个很好理解了,就是划线的宽度</p> <p>3、 path.lineCapStyle 这个线段起点是终点的样式,这个样式有三种:</p> <p>(</p> <p>1、 kCGLineCapButt 该属性值指定不绘制端点, 线条结尾处直接结束。这是默认值。</p> <p>2、 kCGLineCapRound 该属性值指定绘制圆形端点, 线条结尾处绘制一个直径为线条宽度的半圆。</p> <p>kCGLineCapSquare</p> <p>)</p> <p>4、 path.lineJoinStyle 这个属性是用来设置两条线连结点的样式,同样它也有三种样式供我们选择</p> <p>(</p> <p>1、 kCGLineJoinMiter 斜接</p> <p>2、 kCGLineJoinRound 圆滑衔接</p> <p>3、 kCGLineJoinBevel 斜角连接</p> <p>)</p> <p>5、 [path stroke]; 用 stroke 得到的是不被填充的 view , [path fill]; 用 fill 得到的内部被填充的 view,这点在下面的代码还有绘制得到的图片中有,可以体会一下这两者的不同。</p> <p><strong>绘制多边形</strong></p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/d06d11101a8c3ca099809537be2f07a4.png"></p> <p style="text-align: center;">duobianxing.png</p> <p>绘制多边形,实际上就是又一些直线条连成,主要使用 moveToPoint: 和 addLineToPoint: 方法去创建, moveToPoint: 这个方法是设置起始点,意味着从这个点开始,我们就可以使用 addLineToPoint: 去设置我们想要创建的多边形经过的点,也就是两线相交的那个点,用 addLineToPoint: 去创建一个形状的线段,我们可以连续创建line,每一个line的起点都是先前的终点,终点就是指定的点,将线段连接起来就是我们想要创建的多边形了。</p> <pre> #import "DrawPolygonView.h" @implementation DrawPolygonView - (void)drawRect:(CGRect)rect { UIColor *color = [UIColor redColor]; [color set]; //设置线条颜色 UIBezierPath* path = [UIBezierPath bezierPath]; path.lineWidth = 5.0; path.lineCapStyle = kCGLineCapRound; //线条拐角 path.lineJoinStyle = kCGLineJoinRound; //终点处理 [path moveToPoint:CGPointMake(200.0, 50.0)];//起点 // Draw the lines [path addLineToPoint:CGPointMake(300.0, 100.0)]; [path addLineToPoint:CGPointMake(260, 200)]; [path addLineToPoint:CGPointMake(100.0, 200)]; [path addLineToPoint:CGPointMake(100, 70.0)]; [path closePath];//第五条线通过调用closePath方法得到的 // [path stroke];//Draws line 根据坐标点连线 [path fill];//颜色填充 }</pre> <p>在这里我们可以看到最后第五条线是用 [path closePath]; 得到的,closePath方法不仅结束一个shape的subpath表述,它也在最后一个点和第一个点之间画一条线段,这个一个便利的方法我们不需要去画最后一条线了, 哈哈哈哈。这里我们用到的是 [path fill];//颜色填充 进行坐标连点,但是我们看见的是五边形内部被颜色填充了, 如果我们使用 [path stroke]; 那我们得到的就是一个用线画的五边形。</p> <p><strong>画矩形或者正方形</strong></p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/3b0c822ba4c46ec2d4d9dcd5e7011e0f.png"></p> <p style="text-align: center;">juxing.png</p> <p>大家都知道正方形就是特殊的矩形咯,不多讲。只说矩形。</p> <p>使用 + (UIBezierPath *)bezierPathWithRect:(CGRect)rect 这个方法,设置好坐标 frame 就好了,就像我们创建 view 一样,好理解。</p> <pre> - (void)drawRect:(CGRect)rect { UIColor *color = [UIColor redColor]; [color set]; //设置线条颜色 UIBezierPath* path = [UIBezierPath bezierPathWithRect:CGRectMake(20, 20, 100, 80)]; path.lineWidth = 5.0; path.lineCapStyle = kCGLineCapRound; //线条拐角 path.lineJoinStyle = kCGLineJoinRound; //终点处理 [path stroke]; }</pre> <p><strong>创建圆形或者椭圆形</strong></p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/ac65984d2096f027206e33601f78d71a.png"></p> <p style="text-align: center;">yuanxing.png</p> <p>使用 + (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect 这个方法创建圆形或者椭圆形。</p> <p>传入的rect矩形参数绘制一个内切曲线,如果我们传入的rect是矩形就得到矩形的内切椭圆,如果传入的是 正方形得到的就是正方形的内切圆。</p> <pre> - (void)drawRect:(CGRect)rect { UIColor *color = [UIColor redColor]; [color set]; UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:90 startAngle:0 endAngle:TO_RADIAUS(120) clockwise:YES]; path.lineWidth = 5.0; path.lineCapStyle = kCGLineCapRound; path.lineJoinStyle = kCGLineJoinRound; [path stroke]; }</pre> <p><strong>创建一段弧线</strong></p> <p>使用 + (UIBezierPath *)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwis 这个方法创建一段弧线,介绍一下这个方法中的参数:</p> <p>/ <em> </em></p> <p>ArcCenter: 原点</p> <p>radius: 半径</p> <p>startAngle: 开始角度</p> <p>endAngle: 结束角度</p> <p>/</p> <p>弧线的参考系:</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/32ed4163d1ff74e2a2321866aaec3e22.png"></p> <p style="text-align: center;">arc.png</p> <p><strong>绘制二次贝塞尔曲线</strong></p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/d8d79f1ff596987a74dfb88baca8f3d5.png"></p> <p style="text-align: center;">erciquxian.png</p> <p>使用 - (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint 这个方法绘制二次贝塞尔曲线。曲线段在当前点开始,在指定的点结束,</p> <p>一个控制点的切线定义。下图显示了两种曲线类型的相似,以及控制点和curve形状的关系:</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/22456a07fb34919b83f2a501e6b9d408.jpg"></p> <p style="text-align: center;">oneControl.png</p> <pre> - (void)drawRect:(CGRect)rect { UIColor *color = [UIColor redColor]; [color set]; UIBezierPath *path = [UIBezierPath bezierPath]; path.lineWidth = 5.0; path.lineCapStyle = kCGLineCapRound; path.lineJoinStyle = kCGLineJoinRound; /* - (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint Parameters endPoint The end point of the curve. controlPoint The control point of the curve. */ [path moveToPoint:CGPointMake(40, 150)]; [path addQuadCurveToPoint:CGPointMake(140, 200) controlPoint:CGPointMake(20, 40)]; [path stroke]; }</pre> <p><strong>绘制三次贝塞尔曲线</strong></p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/b048814624cd3ea4e589c8308e715000.png"></p> <p style="text-align: center;">sanciquxian.png</p> <p>使用这个方法绘制三次贝塞尔曲线</p> <pre> - (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2 Parameters</pre> <p>这个方法绘制三次贝塞尔曲线。曲线段在当前点开始,在指定的点结束,两个控制点的切线定义。下图显示了两种曲线类型的相似,以及控制点和curve形状的关系:</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/cf910e7de42d6c82384d68f9e7616edc.jpg"></p> <p style="text-align: center;">twoControl.png</p> <pre> - (void)drawRect:(CGRect)rect { /* - (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2 Parameters endPoint The end point of the curve. controlPoint1 The first control point to use when computing the curve. controlPoint2 The second control point to use when computing the curve. */ UIColor *color = [UIColor redColor]; [color set]; UIBezierPath *path = [UIBezierPath bezierPath]; path.lineWidth = 5.0; path.lineCapStyle = kCGLineCapRound; path.lineJoinStyle = kCGLineJoinRound; [path moveToPoint:CGPointMake(20, 200)]; [path addCurveToPoint:CGPointMake(260, 200) controlPoint1:CGPointMake(140, 0) controlPoint2:CGPointMake(140, 400)]; [path stroke]; }</pre> <p><strong>画带圆角的矩形</strong></p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/a00cd564ac4f8362c6434e587d51350e.png"></p> <p style="text-align: center;">daiyuanjuxing.png</p> <p>使用 + (instancetype)bezierPathWithRect:(CGRect)rect; 这个方法绘制,这个方法和 bezierPathWithRect: 类似,绘制一个带内切圆的矩形。</p> <pre> - (void)drawRect:(CGRect)rect { UIColor *color = [UIColor redColor]; [color set]; //设置线条颜色 UIBezierPath* path = [UIBezierPath bezierPathWithRect:CGRectMake(20, 20, 100, 80)]; path.lineWidth = 5.0; path.lineCapStyle = kCGLineCapRound; //线条拐角 path.lineJoinStyle = kCGLineJoinRound; //终点处理 [path stroke]; }</pre> <p><strong>指定矩形的某个角为圆角</strong></p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/e2ae9be8600fb8bc9c996f6b8087dc36.png"></p> <p style="text-align: center;">yuanjiaojuxing.png</p> <p>使用 + (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii; 这个方法绘制。参数的意思:rect 绘制矩形的 frame,corners指定使哪个角为圆角,圆角类型为: <em> </em></p> <p>typedef NS_OPTIONS(NSUInteger, UIRectCorner) {</p> <p>UIRectCornerTopLeft = 1 << 0,</p> <p>UIRectCornerTopRight = 1 << 1,</p> <p>UIRectCornerBottomLeft = 1 << 2,</p> <p>UIRectCornerBottomRight = 1 << 3,</p> <p>UIRectCornerAllCorners = ~0UL</p> <p>};</p> <p>用来指定需要设置的角。cornerRadii 圆角的半径</p> <pre> - (void)drawRect:(CGRect)rect { UIColor *color = [UIColor redColor]; [color set]; UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 100, 100) byRoundingCorners:UIRectCornerTopRight cornerRadii:CGSizeMake(20, 20)]; path.lineCapStyle = kCGLineCapRound; path.lineJoinStyle = kCGLineJoinRound; path.lineWidth = 5.0; [path stroke]; }</pre> <h3><strong>小结:</strong></h3> <p>以上列举的这几种使用贝塞尔曲线绘制图形的方法就是我们在开发中经常能遇到的。当然这块并没有这么简单,还有结合 CAShapeLayer 进行自定义动画等等,有时间会再写一篇相关知识的总结。最后拉上我写的这些方法汇合成的小 demo 供大家体会。</p> <p> </p> <p>来自:http://www.jianshu.com/p/c883fbf52681</p> <p> </p>