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常用的屬性: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的子類有很多,下面說(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;