CALayer、UIBezierPath、CGContextRef的基本使用

Bezier、Layer、View三者之间的关系就好像是画笔、画布、画框的关系。
Bezier:设置画笔的宽度、颜色、开始点、结束点等信息。
Layer:所画的图形都是在layer上画出来(不响应点击事件)。
View:展示画布,本身不具备画图的能力(响应点击时间)。
(只是简单的类比帮助记忆,不准确。靠自己理解)

Layer的使用

Layer我们最常用的就是 View.layer.<#name#>来设置某些视图控件的圆角、阴影等。下面我们了解别的用法:

3485760A-C65C-4D5E-963E-B2664D23BD56.png

我们可以直接在紫色的视图上直接加一个红色的图层

    UIImageView *maskView = [[UIImageView alloc]initWithFrame:CGRectMake(50, 50, 200, 200)];
    maskView.backgroundColor = [UIColor purpleColor];
    [self.view addSubview:maskView];

    CALayer *layer = [CALayer layer];
    layer.frame = CGRectMake(50, 50, 100, 100);
    layer.backgroundColor = [UIColor redColor].CGColor;
    layer.cornerRadius = 6;
    [maskView.layer  addSublayer:layer];
74DE0202-6AE7-43DB-AA96-9F9DC539EB11.png
  //给刚添加的红色图层添加内容
    layer.contents = (id)[UIImage imageNamed:@"<UIBarButtonSystemItem> add"].CGImage;
  //填充内容的contentMode
    layer.contentsGravity = kCAGravityResizeAspect;
    layer.opacity = 0.5;//透明度
B2F69466-98DB-4D1A-BF86-65170E37B56E.png
//注意:取值范围是0~1
    layer.contentsRect = CGRectMake(0, 0, 1, 0.5);//: 表示显示上半部分
//注意:取值范围是0~1
layer.anchorPoint = CGPointMake(0, 0);//anchorPoint是图层的中心点 默认(0.5,0.5) ,设置为多少那么中心点就在那里

Layer 的mask蒙层

这里说明一下mask的属性,mask的属性很简单,例如:view上加了一层imageView,如果imageView.layer.mask = layerA,那么layerA上不透明的部分将会被绘制成透明,透明的部分将会把imageView.layer绘制成透明的图层显示父视图的。


这张图是借用别人的,不过这很形象的说明了mask的应用场景。

256FBA35-9552-4D63-8EEF-FBBC98FAB3A6.png

这个是我实现的结果 底下是一个满屏的图片 然后给layer的内容是这么一个十字架的图片 俩个合成现在的图片

    UIImageView *maskView = [[UIImageView alloc]initWithFrame:self.view.bounds];
    maskView.image = [UIImage imageNamed:@"白胡子.jpg"];
    [self.view addSubview:maskView];
    
    
    CALayer *layer = [CALayer layer];
    layer.frame = CGRectMake(50, 50, 100, 100);
//    layer.backgroundColor = [UIColor redColor].CGColor; 
    layer.cornerRadius = 6;
    //add image
    layer.contents = (id)[UIImage imageNamed:@"<UIBarButtonSystemItem> add"].CGImage;
    //注意:取值范围是0~1
    layer.contentsRect = CGRectMake(0, 0, 1, 1);//: 表示显示全部
    layer.opacity = 0.5;
    layer.edgeAntialiasingMask = kCALayerBottomEdge;
    maskView.layer.mask =layer;

CAShapeLayer 、 CAGradientLayer 是 CALayer的子类

CAShapeLayer 基本用法一般与贝塞尔配合使用

path// 
fillColor//填充图形内部颜色
strokeColor//填充线条的颜色
strokeStart//开始点
strokeEnd//结束点
lineWidth//写的宽度
miterLimit// 斜接长度指的是在两条线交汇处内角和外角之间的距离
lineCap//线条结尾的样子 把线宽设置的大些才能明晰看到
lineJoin//线条之间的结合点的样子 把线宽设置的大些才能明晰看到
fillRule//判断内部外部 见详解 (http://blog.csdn.net/cuixiping/article/details/7848369)
lineDashPhase//线型模板的起始位置
lineDashPattern//线型模板  这是一个NSNumber的数组,索引从1开始记,奇数位数值表示实线长度,偶数位数值表示空白长度
2606B1A0-185D-4BF9-AD1F-4A9680E7B34C.png
    CAShapeLayer *ShapeLayer = [CAShapeLayer layer];
    UIBezierPath *linePath = [UIBezierPath bezierPath];
    [linePath moveToPoint:CGPointMake(10, 200)];
    [linePath addLineToPoint: CGPointMake(200, 300)];
    [linePath addLineToPoint: CGPointMake(300, 10)];
    [linePath addLineToPoint: CGPointMake(10, 200)];
    linePath.lineCapStyle =kCGLineCapRound;
//    [linePath addLineToPoint: CGPointMake(200, 300)];
    ShapeLayer.path = linePath.CGPath;
    ShapeLayer.lineWidth = 10.f;
    ShapeLayer.fillColor = [UIColor redColor].CGColor;
//    ShapeLayer.opacity = 0.5f;
    //画线的开始和结束的地方0-1
//    ShapeLayer.strokeStart = 0.7;
//    ShapeLayer.strokeEnd = 0.8;
    ShapeLayer.strokeColor = [UIColor cyanColor].CGColor;
//    maskView.layer.mask = ShapeLayer;
    ShapeLayer.lineJoin =kCALineJoinRound;
    ShapeLayer.lineCap = kCALineCapRound;
//    ShapeLayer.fillRule = kCAFillRuleEvenOdd;
    ShapeLayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:20], [NSNumber numberWithInt:20], [NSNumber numberWithInt:40], [NSNumber numberWithInt:40], nil];
    ShapeLayer.lineDashPhase = 0;
    
    [maskView.layer addSublayer:ShapeLayer];

CAGradientLayer 的基本用法

利用mask的特性做渐变的字体

    UILabel *textLabel  = [[UILabel alloc]initWithFrame:CGRectMake(100, 200, 200, 20)];
    textLabel.text = @"我爱你Objct-C";
//    textLabel.textColor = [UIColor redColor];
//    textLabel.backgroundColor = [UIColor redColor];
    [self.view addSubview:textLabel];
    
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = textLabel.frame;
    UIColor *beforeColor = [UIColor blueColor];
    UIColor *afterColor = [UIColor redColor];
    // 设置渐变层的颜色
    gradientLayer.colors = @[(id)beforeColor.CGColor,(id)afterColor.CGColor];
    [self.view.layer addSublayer:gradientLayer];//
    textLabel.layer.frame = gradientLayer.bounds;
    gradientLayer.mask = textLabel.layer;//maskview不能作为sub和super  所以不影响背景色
01905598-CC22-48FE-A670-5AF1008CEEF8.png

UIBezierPath 的基本用法

此类是Core Graphics框架关于path的一个封装。使用此类可以定义简单的形状,如椭圆或者矩形,或者有多个直线和曲线段组成的形状。UIBezierPath对象是CGPathRef数据类型的封装。

1.   + (instancetype)bezierPath;//创建并返回一个新的UIBezierPath对象(空的路径)
2.   + (instancetype)bezierPathWithRect:(CGRect)rect;//创建并返回一个新的UIBezierPath对象,使用矩形路径初始化
3.   + (instancetype)bezierPathWithOvalInRect:(CGRect)rect;//创建并返回一个新的椭圆路径的UIBezierPath对象:
4.   + (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; //创建并返回一个新的圆角矩形路径的UIBezierPath对象:
5.   + (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;//参数corners指定了想要需要成为圆角的角。可选值为:UIRectCorner 枚举
6. 
 /**
 *  以某个中心点画弧线
 *  @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;
7.
  /**
 *  根据CGPath创建并返回一个新的UIBezierPath对象
 *  @param CGPath CGPathRef
 */
+ (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;
8.  
/**
 *  设置第一个起始点到接收器
 *  @param point 起点坐标
 */
- (void)moveToPoint:(CGPoint)point;
9.
/**
 *  附加一条直线到接收器的路径
 *  @param point 要到达的坐标
 */
- (void)addLineToPoint:(CGPoint)point;
10.
/**
 *  闭合线 使用这个方法起始点与终点将相连
 */
- (void)closePath;
11.
/**
 *  移除所有坐标点
 */
- (void)removeAllPoints;
12.
- (void)fill;// 填充颜色

- (void)stroke;// 利用当前绘图属性沿着接收器的路径绘制
13.
/**
 *  该方法就是画三次贝塞尔曲线的关键方法,以三个点画一段曲线,一般和moveToPoint:配合使用。其实端点为moveToPoint:设置,终止端点位为endPoint;。控制点1的坐标controlPoint1,这个参数可以调整。控制点2的坐标是controlPoint2。
 *
 *  @param endPoint      终点坐标
 *  @param controlPoint1 控制点1
 *  @param controlPoint2 控制点2  
 */
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;
14.
/**
 *  画二次贝塞尔曲线,是通过调用此方法来实现的。一般和moveToPoint:配合使用。endPoint终端点,controlPoint控制点,对于二次贝塞尔曲线,只有一个控制点
 *  @param endPoint     终点坐标
 *  @param controlPoint 控制点  
 */
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;

这里我就放俩张网络的图片来帮助大家理解三次、二次贝塞尔曲线
三次贝塞尔曲线


二次贝塞尔曲线

图片均来自网络

CGContextRef

此类是Core Graphics框架中的一员。Core Graphics提供了以下几个Graphics Context类型

Bitmap Graphics Context
PDF Graphics Context
Window Graphics Context
Layer Graphics Context
Printer Graphics Context

Graphics Context是图形上下文,是一个CGContextRef类型的数据;可以帮你把你要显示的图形显示到你指定的目标文件上。

在drawRect:方法中取得上下文后,就可以绘制东西到view上
View内部有个layer(图层)属性,drawRect:方法中取得的是一个Layer Graphics Context,因此,绘制的东西其实是绘制到view的layer上去View之所以能显示东西,完全是因为它内部的layer

CGContextRef的一些用法UIBezierPath已经封装好这里也不说了。如果大家有兴趣的可以看 iOS 2D绘图详解CGContextRef 基本认识点

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

推荐阅读更多精彩内容

  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 5,111评论 5 13
  • 前言:关于贝塞尔曲线与CAShapeLayer的学习 学习Demo演示: 贝塞尔曲线简单了解 使用UIBezier...
    麦穗0615阅读 17,870评论 18 149
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,489评论 6 30
  • 目录: 主要绘图框架介绍 CALayer 绘图 贝塞尔曲线-UIBezierPath CALayer子类 补充:i...
    Ryan___阅读 1,673评论 1 9
  • 前言 本文只要描述了iOS中的Core Animation(核心动画:隐式动画、显示动画)、贝塞尔曲线、UIVie...
    GitHubPorter阅读 3,626评论 7 11