CALayer、UIBezierPath、CGContextRef的基本使用

Bezier、Layer、View三者之間的關(guān)系就好像是畫筆、畫布、畫框的關(guān)系。
Bezier:設(shè)置畫筆的寬度、顏色、開始點(diǎn)、結(jié)束點(diǎn)等信息。
Layer:所畫的圖形都是在layer上畫出來(lái)(不響應(yīng)點(diǎn)擊事件)。
View:展示畫布,本身不具備畫圖的能力(響應(yīng)點(diǎn)擊時(shí)間)。
(只是簡(jiǎn)單的類比幫助記憶,不準(zhǔn)確??孔约豪斫猓?/p>

Layer的使用

Layer我們最常用的就是 View.layer.<#name#>來(lái)設(shè)置某些視圖控件的圓角、陰影等。下面我們了解別的用法:

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

我們可以直接在紫色的視圖上直接加一個(gè)紅色的圖層

    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
  //給剛添加的紅色圖層添加內(nèi)容
    layer.contents = (id)[UIImage imageNamed:@"<UIBarButtonSystemItem> add"].CGImage;
  //填充內(nèi)容的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是圖層的中心點(diǎn) 默認(rèn)(0.5,0.5) ,設(shè)置為多少那么中心點(diǎn)就在那里

Layer 的mask蒙層

這里說(shuō)明一下mask的屬性,mask的屬性很簡(jiǎn)單,例如:view上加了一層imageView,如果imageView.layer.mask = layerA,那么layerA上不透明的部分將會(huì)被繪制成透明,透明的部分將會(huì)把imageView.layer繪制成透明的圖層顯示父視圖的。


這張圖是借用別人的,不過(guò)這很形象的說(shuō)明了mask的應(yīng)用場(chǎng)景。

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

這個(gè)是我實(shí)現(xiàn)的結(jié)果 底下是一個(gè)滿屏的圖片 然后給layer的內(nèi)容是這么一個(gè)十字架的圖片 倆個(gè)合成現(xiàn)在的圖片

    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//填充圖形內(nèi)部顏色
strokeColor//填充線條的顏色
strokeStart//開始點(diǎn)
strokeEnd//結(jié)束點(diǎn)
lineWidth//寫的寬度
miterLimit// 斜接長(zhǎng)度指的是在兩條線交匯處內(nèi)角和外角之間的距離
lineCap//線條結(jié)尾的樣子 把線寬設(shè)置的大些才能明晰看到
lineJoin//線條之間的結(jié)合點(diǎn)的樣子 把線寬設(shè)置的大些才能明晰看到
fillRule//判斷內(nèi)部外部 見詳解 (http://blog.csdn.net/cuixiping/article/details/7848369)
lineDashPhase//線型模板的起始位置
lineDashPattern//線型模板  這是一個(gè)NSNumber的數(shù)組,索引從1開始記,奇數(shù)位數(shù)值表示實(shí)線長(zhǎng)度,偶數(shù)位數(shù)值表示空白長(zhǎng)度
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;
    //畫線的開始和結(jié)束的地方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];
    // 設(shè)置漸變層的顏色
    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框架關(guān)于path的一個(gè)封裝。使用此類可以定義簡(jiǎn)單的形狀,如橢圓或者矩形,或者有多個(gè)直線和曲線段組成的形狀。UIBezierPath對(duì)象是CGPathRef數(shù)據(jù)類型的封裝。

1.   + (instancetype)bezierPath;//創(chuàng)建并返回一個(gè)新的UIBezierPath對(duì)象(空的路徑)
2.   + (instancetype)bezierPathWithRect:(CGRect)rect;//創(chuàng)建并返回一個(gè)新的UIBezierPath對(duì)象,使用矩形路徑初始化
3.   + (instancetype)bezierPathWithOvalInRect:(CGRect)rect;//創(chuàng)建并返回一個(gè)新的橢圓路徑的UIBezierPath對(duì)象:
4.   + (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; //創(chuàng)建并返回一個(gè)新的圓角矩形路徑的UIBezierPath對(duì)象:
5.   + (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;//參數(shù)corners指定了想要需要成為圓角的角??蛇x值為:UIRectCorner 枚舉
6. 
 /**
 *  以某個(gè)中心點(diǎn)畫弧線
 *  @param center     指定了圓弧所在正圓的圓心點(diǎn)坐標(biāo)
 *  @param radius     指定了圓弧所在正圓的半徑
 *  @param startAngle 指定了起始弧度位置  注意: 起始與結(jié)束這里是弧度 
 *  @param endAngle   指定了結(jié)束弧度位置  
 *  @param clockwise  指定了繪制方向,以時(shí)鐘方向?yàn)榕袛嗷鶞?zhǔn)   
 */
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;
7.
  /**
 *  根據(jù)CGPath創(chuàng)建并返回一個(gè)新的UIBezierPath對(duì)象
 *  @param CGPath CGPathRef
 */
+ (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;
8.  
/**
 *  設(shè)置第一個(gè)起始點(diǎn)到接收器
 *  @param point 起點(diǎn)坐標(biāo)
 */
- (void)moveToPoint:(CGPoint)point;
9.
/**
 *  附加一條直線到接收器的路徑
 *  @param point 要到達(dá)的坐標(biāo)
 */
- (void)addLineToPoint:(CGPoint)point;
10.
/**
 *  閉合線 使用這個(gè)方法起始點(diǎn)與終點(diǎn)將相連
 */
- (void)closePath;
11.
/**
 *  移除所有坐標(biāo)點(diǎn)
 */
- (void)removeAllPoints;
12.
- (void)fill;// 填充顏色

- (void)stroke;// 利用當(dāng)前繪圖屬性沿著接收器的路徑繪制
13.
/**
 *  該方法就是畫三次貝塞爾曲線的關(guān)鍵方法,以三個(gè)點(diǎn)畫一段曲線,一般和moveToPoint:配合使用。其實(shí)端點(diǎn)為moveToPoint:設(shè)置,終止端點(diǎn)位為endPoint;。控制點(diǎn)1的坐標(biāo)controlPoint1,這個(gè)參數(shù)可以調(diào)整??刂泣c(diǎn)2的坐標(biāo)是controlPoint2。
 *
 *  @param endPoint      終點(diǎn)坐標(biāo)
 *  @param controlPoint1 控制點(diǎn)1
 *  @param controlPoint2 控制點(diǎn)2  
 */
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;
14.
/**
 *  畫二次貝塞爾曲線,是通過(guò)調(diào)用此方法來(lái)實(shí)現(xiàn)的。一般和moveToPoint:配合使用。endPoint終端點(diǎn),controlPoint控制點(diǎn),對(duì)于二次貝塞爾曲線,只有一個(gè)控制點(diǎn)
 *  @param endPoint     終點(diǎn)坐標(biāo)
 *  @param controlPoint 控制點(diǎn)  
 */
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;

這里我就放倆張網(wǎng)絡(luò)的圖片來(lái)幫助大家理解三次、二次貝塞爾曲線
三次貝塞爾曲線


二次貝塞爾曲線

圖片均來(lái)自網(wǎng)絡(luò)

CGContextRef

此類是Core Graphics框架中的一員。Core Graphics提供了以下幾個(gè)Graphics Context類型

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

Graphics Context是圖形上下文,是一個(gè)CGContextRef類型的數(shù)據(jù);可以幫你把你要顯示的圖形顯示到你指定的目標(biāo)文件上。

在drawRect:方法中取得上下文后,就可以繪制東西到view上
View內(nèi)部有個(gè)layer(圖層)屬性,drawRect:方法中取得的是一個(gè)Layer Graphics Context,因此,繪制的東西其實(shí)是繪制到view的layer上去View之所以能顯示東西,完全是因?yàn)樗鼉?nèi)部的layer

CGContextRef的一些用法UIBezierPath已經(jīng)封裝好這里也不說(shuō)了。如果大家有興趣的可以看 iOS 2D繪圖詳解,CGContextRef 基本認(rèn)識(shí)點(diǎn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過(guò)程并不復(fù)雜,今天將帶大家一窺iOS動(dòng)畫全貌。在這里你可以看...
    F麥子閱讀 5,271評(píng)論 5 13
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過(guò)程并不復(fù)雜,今天將帶大家一窺ios動(dòng)畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,696評(píng)論 6 30
  • 目錄: 主要繪圖框架介紹 CALayer 繪圖 貝塞爾曲線-UIBezierPath CALayer子類 補(bǔ)充:i...
    Ryan___閱讀 1,781評(píng)論 1 9
  • 前言 本文只要描述了iOS中的Core Animation(核心動(dòng)畫:隱式動(dòng)畫、顯示動(dòng)畫)、貝塞爾曲線、UIVie...
    GitHubPorter閱讀 3,742評(píng)論 7 11
  • If you want to copy,mirror,translate,or excerpt this ...
    吳黃龍本人閱讀 269評(píng)論 0 0

友情鏈接更多精彩內(nèi)容