CALayer及其子類

CALayer

1.CALayer簡(jiǎn)介

CALayer包含在QuartzCore框架中,這是一個(gè)跨平臺(tái)的框架,既可以用在iOS中又可以用在Mac OS X中。在iOS中乙嘀,我們所看到的視圖UIView是通過(guò)QuartzCore中的CALayer顯示出來(lái)的,我們討論的動(dòng)畫效果也是加在這個(gè)CALayer上的破喻。

2.CALayer屬性

CALayer主要是展示內(nèi)容和動(dòng)畫操作虎谢,CALayer不包含在UIKit中,不能響應(yīng)事件曹质,由于CALayer在設(shè)計(jì)之初就考慮它的動(dòng)畫操作功能婴噩,CALayer很多屬性在修改時(shí)都能形成動(dòng)畫效果擎场,這種屬性稱為“隱式動(dòng)畫屬性”,但是UIView的根Layer是沒(méi)有隱式動(dòng)畫的几莽。另外迅办,UIView的根圖層創(chuàng)建工作完全由iOS負(fù)責(zé)完成,無(wú)法重新創(chuàng)建章蚣,但是可以往根圖層中添加子圖層或移除子圖層站欺。

下表列出了CALayer常用的屬性:
CALayer屬性

3.CALayer的簡(jiǎn)單使用

3.1 設(shè)置UIView根layer

//初始化UIimageView對(duì)象
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"annotation"]];
//設(shè)置陰影
imageView.layer.shadowColor = [UIColor grayColor].CGColor;//顏色
imageView.layer.shadowOffset = CGSizeMake(10, 10);//偏移量
imageView.layer.shadowOpacity = 0.8;//不透明度
//設(shè)置圓角大小
imageView.layer.cornerRadius = 10;
//設(shè)置邊框
imageView.layer.borderWidth = 2;//邊框?qū)挾?imageView.layer.borderColor = [UIColor redColor].CGColor;//邊框顏色

3.2 添加一個(gè)顯示顯示圖片的layer

//初始化layer對(duì)象
CALayer *imageLayer = [CALayer layer];
//設(shè)置圖層的寬高
imageLayer.bounds = CGRectMake(0, 0, 100, 100);
//設(shè)置圖層的位置
imageLayer.position = CGPointMake(200, Height_NavBar+70);
//設(shè)置需要顯示的圖片
imageLayer.contents = (id)[UIImage imageNamed:@"annotation"].CGImage;
// 設(shè)置層的圓角半徑為10
imageLayer.cornerRadius = 10;
// 如果設(shè)置了圖片,需要設(shè)置這個(gè)屬性為YES才有圓角效果
imageLayer.masksToBounds = YES;
//設(shè)置旋轉(zhuǎn)
imageLayer.transform = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);
//添加圖層到控制器的view的layer上
[self.view.layer addSublayer:imageLayer];

4.CALayer繪圖

在使用Quartz 2D繪圖時(shí)纤垂,當(dāng)調(diào)用了UIView的drawRect:方法繪制圖形矾策、圖像,這種方式本質(zhì)還是在圖層中繪制峭沦,下面介紹如何直接在圖層中繪圖贾虽。
圖層繪圖有兩種方法,不管使用哪種方法都要調(diào)用setNeedsDisplay(UIView和CALayer都有setNeedsDisplay方法, 而這里調(diào)用的是圖層的方法)

4.1 使用代理方法繪圖

首先設(shè)置圖層代理吼鱼,實(shí)現(xiàn)代理協(xié)議方法- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx蓬豁,設(shè)置完代理后必須要調(diào)用圖層的setNeedDisplay方法,否則繪制的內(nèi)容無(wú)法顯示蛉抓。

- (void)setupLayerWitdDelegate{
    //初始化layer對(duì)象
    layer = [CALayer layer];
    //設(shè)置圖層的寬高
    layer.bounds = CGRectMake(0, 0, 100, 100);
    //設(shè)置圖層的位置
    layer.position = CGPointMake(70, Height_NavBar+200);
    //設(shè)置圖層代理
    layer.delegate = self;
    //添加圖層到控制器的view的layer上
    [self.view.layer addSublayer:layer];
    //調(diào)用圖層setNeedDisplay,否則代理方法不會(huì)被調(diào)用
    [layer setNeedsDisplay];
}

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
    CGContextSaveGState(ctx);
    
    //圖形上下文形變庆尘,解決圖片倒立的問(wèn)題
    CGContextScaleCTM(ctx, 1, -1);
    CGContextTranslateCTM(ctx, 0, -100);
    
    UIImage *image = [UIImage imageNamed:@"annotation"];
    
    //注意這個(gè)位置是相對(duì)于圖層而言的不是屏幕
    CGContextDrawImage(ctx, CGRectMake(0, 0, 100, 100), image.CGImage);
    
    CGContextRestoreGState(ctx);

}

4.2 使用自定義圖層繪圖

在自定義圖層中繪圖時(shí)只要自己編寫一個(gè)類繼承于CALayer然后在drawInContext:中繪圖即可剃诅。同前面在代理方法繪圖一樣巷送,要顯示圖層中繪制的內(nèi)容也要調(diào)用圖層的setNeedDisplay方法,否則drawInContext方法將不會(huì)調(diào)用矛辕。

- (void)drawInContext:(CGContextRef)ctx{
    CGContextSaveGState(ctx);
    
    //圖形上下文形變笑跛,解決圖片倒立的問(wèn)題
    CGContextScaleCTM(ctx, 1, -1);
    CGContextTranslateCTM(ctx, 0, -100);
    
    UIImage *image = [UIImage imageNamed:@"annotation"];
    
    //注意這個(gè)位置是相對(duì)于圖層而言的不是屏幕
    CGContextDrawImage(ctx, CGRectMake(0, 0, 100, 100), image.CGImage);
    
    CGContextRestoreGState(ctx);   
}

CALayer的子類

CALayer子類

CALayer的子類有很多,下面說(shuō)幾個(gè)比較常用的:

CAShapeLayer

1.CAShapeLayer繼承自CALayer聊品,可使用CALayer的所有屬性
2.CAShapeLayer是在坐標(biāo)系內(nèi)繪制貝塞爾曲線的飞蹂,通過(guò)繪制貝塞爾曲線,設(shè)置shape(形狀)的path(路徑)翻屈,從而繪制各種各樣的圖形以及不規(guī)則圖形陈哑。因此,使用CAShapeLayer需要與UIBezierPath一起使用伸眶。
3.UIBezierPath類允許你在自定義的 View 中繪制和渲染由直線和曲線組成的路徑.惊窖。你可以在初始化的時(shí)候直接為你的UIBezierPath指定一個(gè)幾何圖形。

- (void)setupShapeLayer{
    //創(chuàng)建路徑
    UIBezierPath *path = [[UIBezierPath alloc]init];
    [path moveToPoint:CGPointMake(50, 320)];
    [path addQuadCurveToPoint:CGPointMake(300, 320) controlPoint:CGPointMake(100, 400)];
    [path addQuadCurveToPoint:CGPointMake(50, 320) controlPoint:CGPointMake(100, 350)];
    // 創(chuàng)建 shapeLayer
    CAShapeLayer *shapeLayer = [[CAShapeLayer alloc]init];
    [self.view.layer addSublayer:shapeLayer];
    //呈現(xiàn)的形狀的路徑
    shapeLayer.path = path.CGPath;
    //填充路徑的顏色,默認(rèn)顏色為不透明的黑色厘贼。
    shapeLayer.fillColor = [UIColor redColor].CGColor;
    //設(shè)置描邊色界酒,默認(rèn)無(wú)色。
    shapeLayer.strokeColor = [UIColor greenColor].CGColor;
    //線的寬度嘴秸,默認(rèn)為1
    shapeLayer.lineWidth = 2;
    //lineJoin為線連接類型毁欣,其值也有三個(gè)類型庇谆,分別為kCALineJoinMiter、kCALineJoinRound凭疮、kCALineJoinBevel饭耳,默認(rèn)值是Miter
    shapeLayer.lineJoin = kCALineJoinRound;
    //lineCap為線端點(diǎn)類型,值有三個(gè)類型哭尝,分別為kCALineCapButt 哥攘、kCALineCapRound 、kCALineCapSquare材鹦,默認(rèn)值為Butt
    shapeLayer.lineCap = kCALineCapRound;
    
}

CAGradientLayer

CAGradientLayer繼承自CALayer逝淹,它主要功能是能實(shí)現(xiàn)漸變的顏色
startPoint和endPoint表示顏色的漸變方向,locations是漸變區(qū)域桶唐。

- (void)setupGradintLayer{
    //創(chuàng)建gradientLayer
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.bounds = CGRectMake(0, 0, 100, 100);
    gradientLayer.position = CGPointMake(70, Height_NavBar+370);
    [self.view.layer addSublayer:gradientLayer];
    //漸變顏色的數(shù)組
    gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,
                             (__bridge id)[UIColor blueColor].CGColor];
    //漸變顏色的區(qū)間分布栅葡,默認(rèn)是nil,會(huì)平均分布尤泽。
    gradientLayer.locations =  @[@(0.2), @(0.5), @(0.8)];
    // 起始點(diǎn)
    gradientLayer.startPoint = CGPointMake(0.0, 0.0);
    // 結(jié)束點(diǎn)
    gradientLayer.endPoint = CGPointMake(1.0, 1.0);
}

CAEmitterLayer

CAEmitterLayer 是一個(gè)高性能的粒子引擎欣簇,被用來(lái)創(chuàng)建復(fù)雜的粒子動(dòng)畫如:煙霧,火坯约,雨等效果熊咽,并且很好地控制了性能。
iOS中的粒子效果有兩部分組成闹丐,一部分為發(fā)射器CAEmitterLayer横殴,另一部分是粒子單元CAEmitterCell,用于設(shè)置相應(yīng)的粒子屬性卿拴。

  • CAEmitterLayer的屬性
 發(fā)射源位置衫仑。注意,是一個(gè)空間坐標(biāo)堕花。并且標(biāo)記為 Animatable. 也就是說(shuō)可以用 CoreAnimation 移動(dòng)發(fā)射源位置

@property CGPoint emitterPosition;
@property CGFloat emitterZPosition; 
發(fā)射源大小文狱。注意除了寬和高之外,還有縱向深度缘挽。
文檔中還提到瞄崇,這兩個(gè)屬性有時(shí)候可能會(huì)因?yàn)樵O(shè)置了 emitterShape 而被忽略,具體情況實(shí)際嘗試一下就可以了壕曼。
@property CGSize emitterSize;
@property CGFloat emitterDepth;

CA_EXTERN NSString * const kCAEmitterLayerPoint
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerLine
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerRectangle
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerCuboid
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerCircle
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerSphere
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);

 emitterShape 決定了發(fā)射源的形狀苏研。
@property(copy) NSString *emitterShape;
   
CA_EXTERN NSString * const kCAEmitterLayerPoints
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerOutline
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerSurface
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerVolume
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);

 emitterMode 決定了發(fā)射源的發(fā)射模式。
@property(copy) NSString *emitterMode;

  • CAEmitterCell的屬性
@property float birthRate; //每秒生成多少個(gè)粒子
 
@property float lifetime; //粒子存活的時(shí)間,以秒為單位
@property float lifetimeRange; // 可以為這個(gè)粒子存活的時(shí)間再指定一個(gè)范圍窝稿。
上面兩個(gè)屬性如果只用了lifetime那么粒子的存活時(shí)間就是固定的楣富,比如lifetime=10,那么粒子10s秒后就消失了。
如果使用了lifetimeRange伴榔,比如lifetimeRange=5纹蝴,那么粒子的存活時(shí)間就是在5s~15s這個(gè)范圍內(nèi)消失庄萎。
 
@property CGFloat velocity;//粒子平均初始速度。正數(shù)表示豎直向上塘安,負(fù)數(shù)豎直向下糠涛。
@property CGFloat velocityRange; //可以再指定一個(gè)范圍。
上面兩個(gè)屬性同lifetime和lifetimeRange
 
@property CGFloat xAcceleration;
@property CGFloat yAcceleration;
@property CGFloat zAcceleration; //三者構(gòu)成了一個(gè)空間矢量兼犯。決定了每個(gè)方向上粒子的加速度忍捡。
 
@property CGFloat emissionRange; //以錐形分布開的發(fā)射角度。角度用弧度制切黔。粒子均勻分布在這個(gè)錐形范圍內(nèi)砸脊。
 
@property CGFloat spin;//粒子的平均旋轉(zhuǎn)速度
@property CGFloat spinRange; //可指定一個(gè)范圍∥诚迹弧度制凌埂。
 
@property(strong) id contents; //cell的內(nèi)容。通常是一個(gè)指針CGImageRef诗芜。
 
@property CGColorRef color; //可以把圖片「染」成你想要的顏色瞳抓。

@property(copy) NSString *name; //The name of the cell,用于構(gòu)建key paths伏恐。這也是后面手動(dòng)控制動(dòng)畫開始和結(jié)束的關(guān)鍵孩哑。

CAReplicatorLayer

CAReplicatorLayer是一個(gè)高效處理復(fù)制圖層的中間層。他能復(fù)制圖層的所有屬性翠桦,包括動(dòng)畫横蜒。

  • CAReplicatorLayer的屬性
//指定圖層重復(fù)制多少次
@property NSInteger instanceCount;

//設(shè)置為YES,圖層將保持于CATransformLayer類似的性質(zhì)和相同的限制
@property BOOL preservesDepth;

//復(fù)制延時(shí),一般用在動(dòng)畫上
@property CFTimeInterval instanceDelay;

//3D變換
@property CATransform3D instanceTransform;

//設(shè)置多個(gè)復(fù)制圖層的顏色,默認(rèn)位白色
@property(nullable) CGColorRef instanceColor;

//設(shè)置每個(gè)復(fù)制圖層相對(duì)上一個(gè)復(fù)制圖層的紅色秤掌、綠色愁铺、藍(lán)色鹰霍、透明度偏移量
@property float instanceRedOffset;
@property float instanceGreenOffset;
@property float instanceBlueOffset;
@property float instanceAlphaOffset;

CATextLayer

Core Animation提供了一個(gè)CALayer的子類CATextLayer闻鉴,它以圖層的形式包含了UILabel幾乎所有的繪制特性,并且額外提供了一些新的特性茂洒。

  • CATextLayer的屬性
//渲染的文字字符串
@property(nullable, copy) id string;
//設(shè)置字體
@property(nullable) CFTypeRef font;
//設(shè)置字號(hào)
@property CGFloat fontSize;
//設(shè)置文字顏色
@property(nullable) CGColorRef foregroundColor;
//是否換行
@property(getter=isWrapped) BOOL wrapped;
/*
設(shè)置截?cái)嗄J?NSString * const kCATruncationNone;
截?cái)嗲安糠?NSString * const kCATruncationStart;
截?cái)嗪蟛糠?NSString * const kCATruncationEnd;
截?cái)嘀虚g
NSString * const kCATruncationMiddle;
*/
@property(copy) NSString *truncationMode;
/*
設(shè)置文字對(duì)齊模式
NSString * const kCAAlignmentNatural;
NSString * const kCAAlignmentLeft;
NSString * const kCAAlignmentRight;
NSString * const kCAAlignmentCenter;
NSString * const kCAAlignmentJustified;
*/
@property(copy) NSString *alignmentMode;

參考:完整項(xiàng)目資料下載

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末孟岛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子督勺,更是在濱河造成了極大的恐慌渠羞,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件智哀,死亡現(xiàn)場(chǎng)離奇詭異次询,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)瓷叫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門屯吊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)送巡,“玉大人,你說(shuō)我怎么就攤上這事盒卸∑” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵蔽介,是天一觀的道長(zhǎng)摘投。 經(jīng)常有香客問(wèn)我,道長(zhǎng)虹蓄,這世上最難降的妖魔是什么犀呼? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮薇组,結(jié)果婚禮上圆凰,老公的妹妹穿的比我還像新娘。我一直安慰自己体箕,他們只是感情好专钉,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著累铅,像睡著了一般跃须。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上娃兽,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天菇民,我揣著相機(jī)與錄音,去河邊找鬼投储。 笑死第练,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的玛荞。 我是一名探鬼主播娇掏,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼勋眯!你這毒婦竟也來(lái)了婴梧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤客蹋,失蹤者是張志新(化名)和其女友劉穎塞蹭,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體讶坯,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡番电,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辆琅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漱办。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡担汤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出洼冻,到底是詐尸還是另有隱情崭歧,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布撞牢,位于F島的核電站率碾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏屋彪。R本人自食惡果不足惜所宰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望畜挥。 院中可真熱鬧仔粥,春花似錦、人聲如沸蟹但。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)华糖。三九已至麦向,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間客叉,已是汗流浹背诵竭。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兼搏,地道東北人卵慰。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像佛呻,于是被迫代替她去往敵國(guó)和親裳朋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容