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

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349