博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS,贝塞尔曲线(UIBezierPath)
阅读量:5788 次
发布时间:2019-06-18

本文共 17407 字,大约阅读时间需要 58 分钟。

UIBezierPath简介

  使用UIBezierPath类可以创建基于矢量的路径,这个类在UIKit中。此类是Core Graphics框架关于path的一个封装, UIBezierPath对象是CGPathRef数据类型的封装。。用于定义一个由直线/曲线组合而成的路径, 并且可以在自定义视图中渲染该路径。 

 

UIBezierPath方法和属性

//创建并且返回一个新的 UIBezierPath 对象+ (instancetype) bezierPath;
/**  * 该方法将会创建一个闭合路径, 起始点是 rect 参数的的 origin, 并且按照顺时针方向添加直线, 最终形成矩形  * @param rect:   矩形路径的 Frame  */+ (instancetype)bezierPathWithRect:(CGRect)rect;
/**  * 该方法将会创建一个闭合路径,  该方法会通过顺时针的绘制贝塞尔曲线, 绘制出一个近似椭圆的形状. 如果 rect 参数指定了一个矩形, 那么该 UIBezierPath 对象将会描述一个圆形.  * @param rect:   矩形路径的 Frame  */+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
/**  * 该方法将会创建一个闭合路径,  该方法会顺时针方向连续绘制直线和曲线.  当 rect 为正方形时且 cornerRadius 等于边长一半时, 则该方法会描述一个圆形路径.  * @param rect:   矩形路径的 Frame  * @param cornerRadius:   矩形的圆角半径  */+ (instancetype) bezierPathWithRoundedRect:(CGRect)rect                               cornerRadius:(CGFloat)cornerRadius;
/**  * 该方法将会创建一个闭合路径,  该方法会顺时针方向连续绘制直线和曲线.    * @param rect:   矩形路径的 Frame  * @param corners:   UIRectCorner 枚举类型, 指定矩形的哪个角变为圆角  * @param cornerRadii:   矩形的圆角半径  */+ (instancetype) bezierPathWithRoundedRect:(CGRect)rect                          byRoundingCorners:(UIRectCorner)corners                               cornerRadii:(CGSize)cornerRadii;
/**  * 该方法会创建出一个开放路径, 创建出来的圆弧是圆的一部分. 在默认的坐标系统中, 开始角度 和 结束角度 都是基于单位圆的(看下面这张图). 调用这个方法之后, currentPoint 将会设置为圆弧的结束点.  * 举例来说: 指定其实角度为0, 指定结束角度为π, 设置 clockwise 属性为 YES, 将会绘制出圆的下半部分.  * 然而当我们不修改起始角度 和 结束角度, 我们仅仅将 clockwise 角度设置为 NO, 则会绘制出来一个圆的上半部分.  * @param center:   圆心  * @param radius: 半径  * @param startAngle:   起始角度  * @param endAngle:   结束角度  * @param clockwise:   是否顺时针绘制  */+ (instancetype) bezierPathWithArcCenter:(CGPoint)center                                   radius:(CGFloat)radius                               startAngle:(CGFloat)startAngle                                 endAngle:(CGFloat)endAngle                                clockwise:(BOOL)clockwise;
//通过一个 CGPath, 创建并且返回一个新的 UIBezierPath 对象+ (instancetype) bezierPathWithCGPath:(CGPathRef)CGPath;
/**  * 通过该方法反转一条路径, 并不会修改该路径的样子. 它仅仅是修改了绘制的方向  * @return: 返回一个新的 UIBezierPath 对象, 形状和原来路径的形状一样,  *          但是绘制的方向相反.  */- (UIBezierPath *) bezierPathByReversingPath;
/**  * 如果当前有正在绘制的子路径, 该方法则会隐式的结束当前路径,   * 并将 currentPoint 设置为指定点. 当上一条子路径被终止, 该方法  * 实际上并不会去闭合上一条子路径. 所以上一条自路径的起始点 和  * 结束点并没有被链接.  * 对于大多数构造路径相关的方法而言, 在你绘制直线或曲线之前, 需要先调用这个方法.  * @param point:   当前坐标系统中的某一点  */- (void)moveToPoint:(CGPoint)point;
/**  * 该方法将会从 currentPoint 到 指定点 链接一条直线.   * Note: 在追加完这条直线后, 该方法将会更新 currentPoint 为 指定点  *       调用该方法之前, 你必须先设置 currentPoint. 如果当前绘制路径  *       为空, 并且未设置 currentPoint, 那么调用该方法将不会产生任何  *       效果.  * @param point:   绘制直线的终点坐标, 当前坐标系统中的某一点  */- (void)addLineToPoint:(CGPoint)point;
/**  * 该方法将会从 currentPoint 添加一条指定的圆弧.  * 该方法的介绍和构造方法中的一样. 请前往上文查看  * @param center: 圆心  * @param radius: 半径  * @param startAngle: 起始角度  * @param endAngle: 结束角度  * @param clockwise: 是否顺时针绘制  */- (void)addArcWithCenter:(CGPoint)center                   radius:(CGFloat)radius               startAngle:(CGFloat)startAngle                 endAngle:(CGFloat)endAngle                clockwise:(BOOL)clockwise NS_AVAILABLE_IOS(4_0);
/**  * 该方法将会从 currentPoint 到 指定的 endPoint 追加一条二次贝塞尔曲线.  * currentPoint、endPoint、controlPoint 三者的关系最终定义了二次贝塞尔曲线的形状.  * 二次贝塞尔曲线的弯曲由一个控制点来控制. 如下图所示  * Note: 调用该方法前, 你必须先设置 currentPoint, 如果路径为空,   *       并且尚未设置 currentPoint, 调用该方法则不会产生任何效果.   *       当添加完贝塞尔曲线后, 该方法将会自动更新 currentPoint 为  *       指定的结束点  * @param endPoint: 终点  * @param controlPoint: 控制点  */- (void)addQuadCurveToPoint:(CGPoint)endPoint                controlPoint:(CGPoint)controlPoint;
/**  * 该方法将会从 currentPoint 到 指定的 endPoint 追加一条三次贝塞尔曲线.  * 三次贝塞尔曲线的弯曲由两个控制点来控制. 如下图所示  * Note: 调用该方法前, 你必须先设置 currentPoint, 如果路径为空,   *       并且尚未设置 currentPoint, 调用该方法则不会产生任何效果.   *       当添加完贝塞尔曲线后, 该方法将会自动更新 currentPoint 为  *       指定的结束点  * @param endPoint: 终点  * @param controlPoint1: 控制点1  * @param controlPoint2: 控制点2  */- (void)addCurveToPoint:(CGPoint)endPoint           controlPoint1:(CGPoint)controlPoint1           controlPoint2:(CGPoint)controlPoint2;
/**  * 该方法将会从 currentPoint 到子路经的起点 绘制一条直线,   * 以此来关闭当前的自路径. 紧接着该方法将会更新 currentPoint  * 为 刚添加的这条直线的终点, 也就是当前子路经的起点.  */- (void)closePath;
//删除 UIBezierPath 对象中的所有点, 效果也就等同于删除了所有子路经- (void)removeAllPoints;
/**  * 该方法将会在当前 UIBezierPath 对象的路径中追加  * 指定的 UIBezierPath 对象中的内容.   */- (void)appendPath:(UIBezierPath *)bezierPath;
/**  * 获取这个属性, 你将会获得一个不可变的 CGPathRef 对象,  * 他可以传入 CoreGraphics 提供的函数中  * 你可以是用 CoreGraphics 框架提供的方法创建一个路径,   * 并给这个属性赋值, 当时设置了一个新的路径后,   * 这个将会对你给出的路径对象进行 Copy 操作  */@property(nonatomic) CGPathRef CGPath;
/**  * 该属性的值, 将会是下一条绘制的直线或曲线的起始点.  * 如果当前路径为空, 那么该属性的值将会是 CGPointZero  */@property(nonatomic, readonly) CGPoint currentPoint;
/**  * 线宽属性定义了 `UIBezierPath` 对象中绘制的曲线规格. 默认为: 1.0  */@property(nonatomic) CGFloat lineWidth;
//曲线终点样式/**  * 该属性应用于曲线的终点和起点. 该属性在一个闭合子路经中是无效果的. 默认为: kCGLineCapButt  */@property(nonatomic) CGLineCap lineCapStyle;// CGPath.h/* Line cap styles. */typedef CF_ENUM(int32_t, CGLineCap) {    kCGLineCapButt,    kCGLineCapRound,    kCGLineCapSquare};
//曲线连接点样式/**  * 默认为: kCGLineJoinMiter.  */@property(nonatomic) CGLineJoin lineJoinStyle;// CGPath.h/* Line join styles. */typedef CF_ENUM(int32_t, CGLineJoin) {    kCGLineJoinMiter,    kCGLineJoinRound,    kCGLineJoinBevel};
//内角和外角距离/**  * 两条线交汇处内角和外角之间的最大距离, 只有当连接点样式为 kCGLineJoinMiter  * 时才会生效,最大限制为10  * 我们都知道, 两条直线相交时, 夹角越小, 斜接长度就越大.  * 该属性就是用来控制最大斜接长度的.  * 当我们设置了该属性, 如果斜接长度超过我们设置的范围,   * 则连接处将会以 kCGLineJoinBevel 连接类型进行显示.  */@property(nonatomic) CGFloat miterLimit;
//渲染精度/**  * 该属性用来确定渲染曲线路径的精确度.  * 该属性的值用来测量真实曲线的点和渲染曲线的点的最大允许距离.  * 值越小, 渲染精度越高, 会产生相对更平滑的曲线, 但是需要花费更  * 多的计算时间. 值越大导致则会降低渲染精度, 这会使得渲染的更迅  * 速. flatness 的默认值为 0.6.  * Note: 大多数情况下, 我们都不需要修改这个属性的值. 然而当我们  *       希望以最小的消耗去绘制一个临时的曲线时, 我们也许会临时增  *       大这个值, 来获得更快的渲染速度.  */@property(nonatomic) CGFloat flatness;
/**  * 设置为 YES, 则路径将会使用 基偶规则 (even-odd) 进行填充.  * 设置为 NO,  则路径将会使用 非零规则 (non-zero) 规则进行填充.  */@property(nonatomic) BOOL usesEvenOddFillRule;
//虚线/**  * @param pattern: 该属性是一个 C 语言的数组, 其中每一个元素都是 CGFloat  *                 数组中的元素代表着线段每一部分的长度, 第一个元素代表线段的第一条线,  *                 第二个元素代表线段中的第一个间隙. 这个数组中的值是轮流的. 来解释一下  *                 什么叫轮流的.   *                 举个例子: 声明一个数组 CGFloat dash[] = @{3.0, 1.0};   *                 这意味着绘制的虚线的第一部分长度为3.0, 第一个间隙长度为1.0, 虚线的  *                 第二部分长度为3.0, 第二个间隙长度为1.0. 以此类推.  * @param count: 这个参数是 pattern 数组的个数  * @param phase: 这个参数代表着, 虚线从哪里开始绘制.  *                 举个例子: 这是 phase 为 6. pattern[] = @{5, 2, 3, 2}; 那么虚线将会  *                 第一个间隙的中间部分开始绘制, 如果不是很明白就请继续往下看,  *                 下文实战部分会对虚线进行讲解.  */- (void)setLineDash:(const CGFloat *)pattern              count:(NSInteger)count              phase:(CGFloat)phase;
//重新获取虚线的模式/**  * 该方法可以重新获取之前设置过的虚线样式.  *  Note:  pattern 这个参数的容量必须大于该方法返回数组的容量.  *         如果无法确定数组的容量, 那么可以调用两次该方法, 第一次  *         调用该方法的时候, 传入 count 参数, 然后在用 count 参数  *         来申请 pattern 数组的内存空间. 然后再第二次正常的调用该方法  */- (void)getLineDash:(CGFloat *)pattern               count:(NSInteger *)count              phase:(CGFloat *)phase;
//填充路径/**  * 该方法当前的填充颜色 和 绘图属性对路径的封闭区域进行填充.  * 如果当前路径是一条开放路径, 该方法将会隐式的将路径进行关闭后进行填充  * 该方法在进行填充操作之前, 会自动保存当前绘图的状态, 所以我们不需要  * 自己手动的去保存绘图状态了.   */- (void)fill;
//使用混合模式进行填充/**  * 该方法当前的填充颜色 和 绘图属性 (外加指定的混合模式 和 透明度)   * 对路径的封闭区域进行填充. 如果当前路径是一条开放路径, 该方法将  * 会隐式的将路径进行关闭后进行填充  * 该方法在进行填充操作之前, 会自动保存当前绘图的状态, 所以我们不需要  * 自己手动的去保存绘图状态了.   *  * @param blendMode: 混合模式决定了如何和已经存在的被渲染过的内容进行合成  * @param alpha: 填充路径时的透明度  */- (void)fillWithBlendMode:(CGBlendMode)blendMode                     alpha:(CGFloat)alpha;
//绘制路径- (void)stroke;
/**  * @param blendMode: 混合模式决定了如何和已经存在的被渲染过的内容进行合成  * @param alpha: 填充路径时的透明度  */- (void)strokeWithBlendMode:(CGBlendMode)blendMode                      alpha:(CGFloat)alpha;
//剪切路径/**  *  该方法将会修改当前绘图上下文的可视区域.  *  当调用这个方法之后, 会导致接下来所有的渲染  *  操作, 只会在剪切下来的区域内进行, 区域外的  *  内容将不会被渲染.  *  如果你希望执行接下来的绘图时, 删除剪切区域,  *  那么你必须在调用该方法前, 先使用 CGContextSaveGState 方法  *  保存当前的绘图状态, 当你不再需要这个剪切区域  *  的时候, 你只需要使用 CGContextRestoreGState 方法  *  来恢复之前保存的绘图状态就可以了.  * @param blendMode: 混合模式决定了如何和  *                   已经存在的被渲染过的内容进行合成  * @param alpha: 填充路径时的透明度  */- (void)addClip;
//是否包含某个点/**  *  该方法返回一个布尔值, 当曲线的覆盖区域包含  * 指定的点(内部点), 则返回 YES, 否则返回 NO.   * Note: 如果当前的路径是一个开放的路径, 那么  *       就算指定点在路径覆盖范围内, 该方法仍然会  *       返回 NO, 所以如果你想判断一个点是否在一个  *       开放路径的范围内时, 你需要先Copy一份路径,  *       并调用 -(void)closePath; 将路径封闭, 然后  *       再调用此方法来判断指定点是否是内部点.  * @param point: 指定点.  */- (BOOL) containsPoint:(CGPoint)point;
//路径是否为空/**  * 检测当前路径是否绘制过直线或曲线.  * Note: 记住, 就算你仅仅调用了 moveToPoint 方法  *       那么当前路径也被看做不为空.  */@property (readonly, getter=isEmpty) BOOL empty;
//路径覆盖的矩形区域/**  * 该属性描述的是一个能够完全包含路径中所有点  *  的一个最小的矩形区域. 该区域包含二次贝塞尔  *  曲线和三次贝塞尔曲线的控制点.  */@property (nonatomic, readonly) CGRect bounds;
/**  * 该方法将会直接对路径中的所有点进行指定的放射  * 变换操作.   */- (void)applyTransform:(CGAffineTransform)transform;

 

UIBezierPath使用方式

*使用CAShapeLayer直接添加在视图图层上

//用CAShapeLayer渲染一个简单的火柴人-(void)createMatchPeople{    //使用UIBezierPath创建图层路径    UIBezierPath *path=[[UIBezierPath alloc] init];    [path moveToPoint:CGPointMake(175, 100)];    [path addArcWithCenter:CGPointMake(150, 100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];    [path moveToPoint:CGPointMake(150, 125)];    [path addLineToPoint:CGPointMake(150, 175)];    [path addLineToPoint:CGPointMake(125, 225)];    [path moveToPoint:CGPointMake(150, 175)];    [path addLineToPoint:CGPointMake(175, 225)];    [path moveToPoint:CGPointMake(100, 150)];    [path addLineToPoint:CGPointMake(200, 150)];            //创建CAShapeLayer    CAShapeLayer *shapeLayer=[CAShapeLayer layer];    shapeLayer.strokeColor=[UIColor redColor].CGColor;    shapeLayer.fillColor=[UIColor clearColor].CGColor;    shapeLayer.lineWidth=5;    shapeLayer.lineJoin=kCALineJoinRound;    shapeLayer.lineCap=kCALineCapRound;    shapeLayer.path=path.CGPath;    [self.view.layer addSublayer:shapeLayer];}

 

*自定义UIView中绘制和渲染

//自定义TestBezierPathView.m

 

////  TestBezierPathView.m//  UIBezierPathLearn////  Created by Vie on 2017/8/15.//  Copyright © 2017年 Vie. All rights reserved.//#import "TestBezierPathView.h"@implementation TestBezierPathView- (void)drawRect:(CGRect)rect {    [self createIndicatorArrow];}//指标箭头-(void)createIndicatorArrow{    UIBezierPath* p = [UIBezierPath bezierPath];    // 绘制一个黑色的垂直黑色线,作为箭头的杆子    [p moveToPoint:CGPointMake(100,100)];    [p addLineToPoint:CGPointMake(100, 19)];    [p setLineWidth:20];    [p stroke];    // 绘制一个红色三角形箭头    [[UIColor redColor] set];    [p removeAllPoints];    [p moveToPoint:CGPointMake(80,25)];    [p addLineToPoint:CGPointMake(100, 0)];    [p addLineToPoint:CGPointMake(120, 25)];    [p fill];    // 从箭头杆子上裁掉一个三角形    [p removeAllPoints];    [p moveToPoint:CGPointMake(90,101)];    [p addLineToPoint:CGPointMake(100, 90)];    [p addLineToPoint:CGPointMake(110, 101)];    // 从箭头杆子上裁掉一个三角形,使用清除混合模式,背景为无色或透明的话裁剪区域就是透明,否则为黑色    [p fillWithBlendMode:kCGBlendModeClear alpha:1.0];}//画圆角矩形-(void)createRoundedRectangle{    //四个角都是圆角    UIBezierPath *path=[UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 70, 70) cornerRadius:10];;    //设置画笔颜色    UIColor *yellowColor=[UIColor yellowColor];    [yellowColor set];    [path stroke];        //指定方向上的角为圆角    UIBezierPath *path2=[UIBezierPath bezierPathWithRoundedRect:CGRectMake(20, 20, 140, 140) byRoundingCorners:UIRectCornerTopLeft|UIRectCornerBottomRight cornerRadii:CGSizeMake(10, 10)];    //设置画笔颜色    UIColor *cyanColor=[UIColor cyanColor];    [cyanColor set];    [path2 stroke];}//渲染BezierPath对象的内容-(void)createDrawingBezierPath{    //创造一个椭圆形的轮廓    UIBezierPath *path=[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 100)];    //设置渲染颜色    [[UIColor yellowColor] setStroke];    [[UIColor redColor] setFill];    //调整graphic context相对于调整path对象的points是首选的方法,因为我们可以很容易的保存和撤销先前的graphics state。    CGContextRef ref=UIGraphicsGetCurrentContext();    CGContextTranslateCTM(ref, 10, 50);    path.lineWidth=5;    [path fill];    [path stroke];}//使用Core Graphics函数和UIBezierPath函数混合方法-(void)createPathDataAndBezierPath{    UIColor *cyanColor=[UIColor cyanColor];    [cyanColor set];//设置线条颜色    //应该生成一个副本,然后修改此副本,然后赋值此副本给CGPath属性    UIBezierPath *path=[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 300, 300)];    CGPathRef cgPath=path.CGPath;    CGMutablePathRef mutablePath=CGPathCreateMutableCopy(cgPath);    CGPathAddEllipseInRect(mutablePath, NULL, CGRectMake(50, 50, 200, 200));    path.CGPath=mutablePath;    [path stroke];    CGPathRelease(mutablePath);    }//使用CoreGraphics函数去修改path-(void)createPathData{    UIColor *cyanColor=[UIColor cyanColor];    [cyanColor set];//设置线条颜色    //创建路径数据    CGMutablePathRef cgPath=CGPathCreateMutable();    //矩形内切圆或椭圆    CGPathAddEllipseInRect(cgPath, NULL, CGRectMake(0, 0, 300, 300));    CGPathAddEllipseInRect(cgPath, NULL, CGRectMake(50, 50, 200, 150));    //创建贝塞尔曲线    UIBezierPath *path=[UIBezierPath bezierPath];    path.CGPath=cgPath;    [path stroke];    CGPathRelease(cgPath);}//使用三次贝塞尔曲线-(void)createThreeBezierCurve{    UIColor *magentaColor=[UIColor magentaColor];    [magentaColor set];    //绘制三次贝塞尔曲线;曲线段在当前点开始,在指定的点结束。曲线的形状有开始点,结束点,两个控制点的切线定义。    UIBezierPath *path=[UIBezierPath bezierPath];    path.lineWidth=5.0;    [path moveToPoint:CGPointMake(0, 150)];    [path addCurveToPoint:CGPointMake(180, 0) controlPoint1:CGPointMake(60, 0) controlPoint2:CGPointMake(120, 150)];    [path stroke];}//使用二次贝塞尔曲线-(void)createSecondaryBezierCurve{    UIColor *purpleColor=[UIColor purpleColor];    [purpleColor set];    //绘制二次贝塞尔曲线;曲线段在当前点开始,在指定的点结束。曲线的形状有开始点,结束点,一个控制点的切线定义。    UIBezierPath *path=[UIBezierPath bezierPath];    path.lineWidth=5.0;    [path moveToPoint:CGPointMake(20, 300)];    [path addQuadCurveToPoint:CGPointMake(120, 300) controlPoint:CGPointMake(70, 0)];    [path stroke];}//创建一段弧线-(void)createArc{    UIColor *brownColor=[UIColor brownColor];    [brownColor set];    //使用UIBezierPath创建一段弧线;圆弧中心,半径,开始角度,结束角度,是否顺时针方向    UIBezierPath *path=[UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:80 startAngle:0 endAngle:M_PI_2 clockwise:NO];    path.lineWidth=5.0f;    [path stroke];}//创建圆形或椭圆-(void)createCircularOrEllipse{    UIColor *cyanColor=[UIColor cyanColor];    [cyanColor set];//设置线条颜色    //创建圆形或椭圆,根据传入的rect矩形参数绘制一个内切曲线    UIBezierPath *path=[UIBezierPath bezierPathWithOvalInRect:CGRectMake(20, 20, 100, 100)];    path.lineWidth=5.0;    [path stroke];}//创建矩形-(void)createRectangular{    UIColor *orangeColor=[UIColor cyanColor];    [orangeColor set];//设置线条颜色    //创建矩形    UIBezierPath *path=[UIBezierPath bezierPathWithRect:CGRectMake(20, 20,100 , 100)];    path.lineWidth=5.0;    [path stroke];}//创建五边形-(void)createPentagon{    UIColor *redColor=[UIColor redColor];    [redColor set];//设置线条颜色    UIBezierPath *path=[UIBezierPath bezierPath];    path.lineWidth=5.0;    path.lineCapStyle=kCGLineCapRound;//线条拐角    path.lineJoinStyle=kCGLineCapRound;//终点处理    [path moveToPoint:CGPointMake(100.0, 0.0)];        //画线    [path addLineToPoint:CGPointMake(200.0, 40.0)];    [path addLineToPoint:CGPointMake(160.0, 140.0)];    [path addLineToPoint:CGPointMake(40.0, 140.0)];    [path addLineToPoint:CGPointMake(0.0, 40.0)];    [path closePath];//第五条线通过调用closePath方法得到的    [path stroke];//使用当前的绘图属性在接收方的路径上画一条线。//    [path fill];//用当前的绘图特性绘制受接收器路径所包围的区域。}-(void)test{    // 1. 随便画一个路径出来.    UIBezierPath *path = [UIBezierPath bezierPath];    [path moveToPoint: CGPointMake(10, 10)];    [path addLineToPoint: CGPointMake(80, 40)];    [path addLineToPoint: CGPointMake( 40,  80)];    [path addLineToPoint: CGPointMake(40, 40)];    path.lineWidth = 3;        // 2. 为这条路径制作一个反转路径    UIBezierPath *reversingPath = [path bezierPathByReversingPath];    reversingPath.lineWidth = 3;        // 3. 为了避免两条路径混淆在一起, 我们为第一条路径做一个位移    CGAffineTransform transform = CGAffineTransformMakeTranslation(200, 0);    [path applyTransform: transform];        // 4. 两条路径分别添加一条直接到 self.center    [path addLineToPoint: CGPointMake(self.frame.size.width*0.5, self.frame.size.height*0.5)];    [reversingPath addLineToPoint: CGPointMake(self.frame.size.width*0.5, self.frame.size.height*0.5)];        // 5. 设置颜色, 并绘制路径    [[UIColor redColor] set];    [path stroke];        [[UIColor greenColor] set];    [reversingPath stroke];}- (void) typeDashLine {        // 1. 先创建三条路径, 有对比更有助于理解    UIBezierPath *path = [UIBezierPath bezierPath];    [path moveToPoint: CGPointMake(80, 40)];    [path addLineToPoint: CGPointMake(self.frame.size.width - 40, 40)];    path.lineWidth = 2;            UIBezierPath *path1 = [UIBezierPath bezierPath];    [path1 moveToPoint: CGPointMake(80, 80)];    [path1 addLineToPoint: CGPointMake(self.frame.size.width - 40, 80)];    path1.lineWidth = 2;            UIBezierPath *path2 = [UIBezierPath bezierPath];    [path2 moveToPoint: CGPointMake(80, 120)];    [path2 addLineToPoint: CGPointMake(self.frame.size.width - 40, 120)];    path2.lineWidth = 2;        // 2.  这部分是配置三条路径虚线的规格, 重点主要是这部分.    CGFloat dashLineConfig[] = {
8.0, 4.0}; [path setLineDash: dashLineConfig count: 2 phase: 0]; CGFloat dashLineConfig1[] = {
8.0, 4.0, 16.0, 8.0}; [path1 setLineDash: dashLineConfig1 count: 4 phase: 0]; CGFloat dashLineConfig2[] = {
8.0, 4.0, 16.0, 8.0}; [path2 setLineDash: dashLineConfig2 count: 4 phase: 12]; // 3. 绘制 [[UIColor orangeColor] set]; [path stroke]; [path1 stroke]; [path2 stroke];}@end

 

 

 

转载于:https://www.cnblogs.com/douniwanxia/p/7416995.html

你可能感兴趣的文章
C#反射实例应用--------获取程序集信息和通过类名创建类实例
查看>>
VC中实现文字竖排的简单方法
查看>>
会话标识未更新
查看>>
阿里架构师:程序员必须掌握的几项核心技术能力
查看>>
程序员常用的六大技术博客类
查看>>
Iceworks 2.8.0 发布,自定义你的 React 模板
查看>>
胖哥学SpringMVC:请求方式转换过滤器配置
查看>>
Kotlin 更加优雅的 Builder - 理解 with
查看>>
前端日拱一卒D6——字符编码与浏览器解析
查看>>
深入理解浏览器的缓存机制
查看>>
微软向Linux社区开放60000多项专利:对开源微软是认真的
查看>>
Hoshin Kanri在丰田的应用
查看>>
又拍云沈志华:如何打造一款安全的App
查看>>
克服大数据集群的挑战
查看>>
PostgreSQL并发控制(MVCC, 事务,事务隔离级别)
查看>>
DM***的第二阶段OSPF
查看>>
20180702搭建青岛RAC记录
查看>>
Spring Security OAuth 实现OAuth 2.0 授权
查看>>
linux文件及简单命令学习
查看>>
dubbo源码分析-架构
查看>>