美文网首页iOS_不断学习iOS CoreGraphic
iOS UIBezierPath贝塞尔曲线那些必须知道的事!

iOS UIBezierPath贝塞尔曲线那些必须知道的事!

作者: iOS_Gato_老猫 | 来源:发表于2019-12-23 11:00 被阅读0次

    UIBezierPath

    • 这个类在UIKit中, 是Core Graphics框架关于path的一个封装,使用此类可以定义简单的形状,比如我们常用到,矩形,圆形,椭圆,弧,或者不规则的多边形

    一.贝塞尔曲线的方法初解

    1.1创建对象

    + (instancetype)bezierPath;
    

    1.2用一条CGPath初始化另一条path。

    + (instancetype)bezierPathWithRect:(CGRect)rect;
    

    1.3创建一个椭圆或者圆

    + (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
    

    1.4创建一个带有圆角的矩形

    // @param rect 矩形区域
    // @param cornerRadii 圆角半径
    + (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius;
    

    1.5创建一个指定某有个角为圆角的矩形 可以多选

    /**
     @param rect 矩形区域
     @param corners 枚举:哪个角是圆角(多个时用 ‘|’分开)
     @param cornerRadii 圆角半径
     */
    + (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;
    

    1.6创建一个圆弧路径

    /**
     @param center 圆心
     @param radius 半径
     @param startAngle 开始角度(0-M_PI)
     @param endAngle 结束角度
     @param clockwise 是否顺时针
     */
    + (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;
    
    

    1.7根据CGPath创建对象

    + (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;
    

    1.8设置起点

    - (void)moveToPoint:(CGPoint)point;
    

    1.9添加一段直线

    - (void)addLineToPoint:(CGPoint)point;
    

    1.10添加一段三次贝塞尔曲线

    /**
     @param endPoint 结束点
     @param controlPoint1 控制点1
     @param controlPoint2 控制点2
     */
    - (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;
    

    1.11添加一段二次贝塞尔曲线

    /**
    @param endPoint 结束点
    @param controlPoint 控制点
    */
    - (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;
    

    1.12添加一段圆弧

    /**
     @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);
    
    

    1.13闭合绘制[终点 连接 起点的线]

    - (void)closePath;
    

    1.14删除所有绘制线,用于更改 或者清空绘制线 [不过这个方法单独使用好像没有用,建议清空后把path也一起删了]

    - (void)removeAllPoints;
    

    1.15绘制整合,将多个path添加到一个path上 可以理解成为 数组里面再存一个数组 差不多这样

    - (void)appendPath:(UIBezierPath *)bezierPath;
    

    1.16起点变成终点,终点变成起点

    - (UIBezierPath *)bezierPathByReversingPath API_AVAILABLE(ios(6.0));
    

    1.17用于平移某一个path

    // 例:向右平移150
    CGAffineTransform transform = CGAffineTransformMakeTranslation(150, 0);
    [path_b applyTransform: transform];
    
    - (void)applyTransform:(CGAffineTransform)transform;
    

    1.18Drawing properties 绘制属性

      // 设置线宽
    @property(nonatomic) CGFloat lineWidth;
    
    //线条拐角[枚举类型]
    /*
    //kCGLineCapButt,     // 无端点      
    //kCGLineCapRound,    // 圆形端点  
    //kCGLineCapSquare    // 方形端点
    */
    @property(nonatomic) CGLineCap lineCapStyle;
    
    //转角位置 样式
    //kCGLineJoinMiter,    // 尖角
    //kCGLineJoinRound,    // 圆角
    //kCGLineJoinBevel     // 缺角
    @property(nonatomic) CGLineJoin lineJoinStyle;
    
    //最大斜接长度(只有在使用kCGLineJoinMiter是才有效), 边角的角度越小,斜接长度就会越大,为了避免斜接长度过长,使用lineLimit属性限制,如果斜接长度超过miterLimit,边角就会以KCALineJoinBevel类型来显示
    @property(nonatomic) CGFloat miterLimit; // Used when lineJoinStyle is kCGLineJoinMiter
    
    //平面度。没用过不了解什么意思
    @property(nonatomic) CGFloat flatness;
    
    //使用偶奇数填充规则。
    @property(nonatomic) BOOL usesEvenOddFillRule; // Default is NO. When YES, the even-odd fill rule is used for drawing, clipping, and hit testing.
    

    1.19 关键方法

    //填充内部,当绘制线成为闭环的时候 内部会填充成你想要的颜色
    - (void)fill;
    
    //不填充,.只有线闭环
    - (void)stroke;
    
    //使用时 只需要使用 [color fill]; 即可
    
    

    1.20 其他方法

    //只有在path里才能看见,其他的切了。
    - (void)addClip;
    

    以上就是 UIBezierPath 的初始化方法
    下面我们开始讲解 贝塞尔曲线的简单应用,主要是在实际使用中 的初始化方法与一些参数选择


    二 UIBezierPath的简单应用

    2.1直线

    - (void)drawRect:(CGRect)rect {
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:CGPointMake(300, 300)];
        [path addLineToPoint:CGPointMake(100, 100)];
        path.lineWidth = 10;
        [[UIColor redColor] setStroke];
        path.lineJoinStyle = kCGLineJoinRound;
        [path stroke];
    }
    
    直线.png

    2.2圆形

    - (void)drawRect:(CGRect)rect {
        UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 100, 300, 300)];
        path.lineWidth = 10;
        [[UIColor redColor] setStroke];
        path.lineJoinStyle = kCGLineJoinRound;
        [path stroke];//
    }
    
    yuanxing.png

    2.3矩形

    - (void)drawRect:(CGRect)rect {
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 100, 200, 200) cornerRadius:1];
        path.lineWidth = 10;
        [[UIColor redColor] setStroke];
        [path stroke];//
    }
    
    juxing1.png
    - (void)drawRect:(CGRect)rect {
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 100, 200, 200) cornerRadius:50];
        path.lineWidth = 10;
        [[UIColor redColor] setStroke];
        [path stroke];//
    }
    
    juxing2.png

    可有看到 只是更改了 cornerRadius 参数 就可以改变原角度 如果改成100那么它就变成了一个圆~~~

    2.4特定的角为圆角的矩形

    - (void)drawRect:(CGRect)rect {
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 100, 200, 200) byRoundingCorners:UIRectCornerBottomRight cornerRadii:CGSizeMake(50,50)];
            
        path.lineWidth = 10.0f;
            
        [path closePath];
            
        [path stroke];
    }
    
    juxing3.png

    2.5圆弧

    - (void)drawRect:(CGRect)rect {
          UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 300) radius:50 startAngle:0 endAngle:M_PI clockwise:YES];
          
          path.lineWidth = 5.0f;
          
          [path stroke];
    }
    
    yuanhu.png

    2.6三次转折曲线

    - (void)drawRect:(CGRect)rect {
            UIBezierPath *path = [UIBezierPath bezierPath];
           
           [path moveToPoint:CGPointMake(100, 100)];
           
           [path addCurveToPoint:CGPointMake(300, 100) controlPoint1:CGPointMake(150, 200) controlPoint2:CGPointMake(250, 0)];
           
           [[UIColor redColor] setStroke];
           
           path.lineWidth = 5;
           
           [path stroke];
    }
    
    sanzhuanzhe.png

    以上就是贝塞尔曲线的简单应用,在实际应用中 如果你能熟练操作以上内容那么 80%的绘制都没问题了


    三. 贝塞尔进阶应用

    3.1二次曲线和三次曲线

    网上找的一些图 个人水平有限 真的画不出来

    111.jpg 222.jpg

    3.2通过shapeLayer画线
    使用此方法 可以不再view的drawRect方法中继续操作 不过如果需要大批量绘制 那么建议还是不要用这个了

    //ShapeLayer  
    -(void)layerAnimation  
    {  
        //贝塞尔画圆  
        UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:100 startAngle:0 endAngle:M_PI clockwise:NO];  
          
        //初始化shapeLayer  
        self.myShapeLayer = [CAShapeLayer layer];  
        _myShapeLayer.frame = _redView.bounds;  
      
        _myShapeLayer.strokeColor = [UIColor greenColor].CGColor;//边沿线色   
        _myShapeLayer.fillColor = [UIColor grayColor].CGColor;//填充色  
          
        _myShapeLayer.lineJoin = kCALineJoinMiter;//线拐点的类型  
        _myShapeLayer.lineCap = kCALineCapSquare;//线终点  
                
        //从贝塞尔曲线获得形状  
        _myShapeLayer.path = path.CGPath;  
          
        //线条宽度  
        _myShapeLayer.lineWidth = 10;  
          
        //起始和终止  
        _myShapeLayer.strokeStart = 0.0;  
        _myShapeLayer.strokeEnd = 1.0;  
                
        //将layer添加进图层  
        [self.redView.layer addSublayer:_myShapeLayer];          
    }  
    
    

    暂时还没有写一个规划比较完善的demo。等以后有时间写好了 再补吧
    附上最近用贝塞尔写的一个 CAD地图的demo 效果图


    cad1.png cad2.png cad3.png CADGif.gif

    相关文章

      网友评论

        本文标题:iOS UIBezierPath贝塞尔曲线那些必须知道的事!

        本文链接:https://www.haomeiwen.com/subject/bfqznctx.html