一、CALayer的常用屬性
-
1、@propertyCGPoint position;?
圖層中心點的位置,類似與UIView的center;用來設置CALayer在父層中的位置;以父層的左上角為原點(0,0); -
2、 @property CGPoint anchorPoint;?
稱『定位點』、『錨點』,該描述是相對于x、y位置比例而言的默認在圖像中心點(0.5、0.5)的位置;決定著CALayer身上的哪個點會再position屬性所指的位置,以自己的左上角為原點(0,0);它的x、y取值范圍都是0~1。 -
3、 @property(nullable) CGColorRef backgroundColor;?
圖層背景顏色 -
4、 @property(nullable) CGColorRef borderColor;?
圖層邊框顏色 -
5、 @property CGFloat borderWidth;?
圖層邊框寬度 -
6、 @property CGRect bounds;?
圖層大小 -
7、 @property(nullable, strong) id contents;?
圖層顯示內容,例如可以將圖片作為圖層內容顯示 -
8、 @property CGRect contentsRect;?
圖層顯示內容的大小和位置 -
9、 @property CGFloat cornerRadius;?
圓角半徑 -
10、 @property(getter=isDoubleSided) BOOL doubleSided;?
圖層背景是否顯示,默認是YES -
11、 @property CGRect frame;?
圖層大小和位置,不支持隱式動畫,所以CALyaer中很少使用frame,通常使用bound和position代替 -
12、 @property(getter=isHidden) BOOL hidden;?
是否隱藏 -
13、 @property(nullable, strong) CALayer *mask;?
圖層蒙版 -
14、 @property BOOL masksToBounds;?
子圖層是否剪切圖層邊界,默認是NO -
15、 @property float opacity;?
圖層透明度,類似與UIView的alpha -
16、 @property(nullable) CGColorRef shadowColor;?
陰影顏色 -
17、 @property CGSize shadowOffset;?
陰影偏移量 -
18、 @property float shadowOpacity;?
陰影透明度,注意默認為0,如果設置陰影必須設置此屬性 -
19、 @property(nullable) CGPathRef shadowPath;?
陰影形狀 -
20、 @property CGFloat shadowRadius;?
陰影模糊半徑 -
21、 @property(nullable, copy) NSArray
二、CALayer不常用屬性
-
1、 @property CGFloat zPosition;?
圖層中心點在z軸中的位置 -
2、 @property CGFloat anchorPointZ;?
圖層在z軸中的錨點; -
3、 - (CGAffineTransform)affineTransform;
-
4、- (void)setAffineTransform:(CGAffineTransform)m;?
以上屬性為圖層形變;該屬性值指定一個CGAffineTransform對象,該對象代表對CALayer執行X、Y兩個維度(也就是平面)上的旋轉、縮放、位移、斜切、鏡像等變換矩陣 -
5、 @property(nullable, readonly) CALayer *superlayer;?
圖層的父圖層
三、CALayer圖層操作
-
1、 - (void)addSublayer:(CALayer *)layer;?
添加子圖層 -
2、 - (void)removeFromSuperlayer;?
將自己從父圖層中移除 -
3、 - (void)insertSublayer:(CALayer *)layer atIndex:(unsigned)idx;?
在自己子圖層數組中的第idx位置添加圖層 -
4、 - (void)insertSublayer:(CALayer?)layer below:(nullable CALayer?)sibling;?
將圖層layer添加在子圖層sibling的下面 -
5、 - (void)insertSublayer:(CALayer?)layer above:(nullable CALayer?)sibling;?
將圖層layer添加在子圖層sibling的上面 -
6、 - (void)replaceSublayer:(CALayer?)layer with:(CALayer?)layer2;?
將圖層layer替換layer2;
四、CALayer動畫操作
-
1、 - (void)addAnimation:(CAAnimation?)anim forKey:(nullable NSString?)key;?
圖層添加某一屬性的動畫 -
2、 - (nullable NSArray< NSString?>?)animationKeys;?
獲取所有動畫的屬性 -
3、 - (nullable CAAnimation?)animationForKey:(NSString?)key;?
獲取某一屬性的動畫 -
4、 - (void)removeAnimationForKey:(NSString *)key;?
移除某一屬性動畫 -
5、 - (void)removeAllAnimations;?
移除所有動畫
五、隱式動畫
在ios中CALayer的設計主要是為了內容展示和動畫操作,CALayer本身并不包含在UIKit中,它不能響應事件。由于CALayer在設計之初就考慮它的動畫操作功能,CALayer很多屬性在修改時都能形成動畫效果,這種屬性稱為『隱式動畫屬性』。但是對于UIView的根視圖層而言屬性的修改并不形成動畫效果,因為很多情況下根圖層更多的充當容器的作用,如果它的屬性變動形成動畫效果會直接影響子圖層。另外,UIView的根圖層創建工作完全有iOS負責完成,無法重新創建,但是可以往根圖層中添加子圖層或移除子圖層。
-
1、如何查看CALayer的某個屬性是否支持隱式動畫
- 可以查看頭文件,看有沒有Animatable,如果有表示支持;?
- 查看官方文檔
?
- 下面標明都支持隱式動畫
- 可以查看頭文件,看有沒有Animatable,如果有表示支持;?
-
2、例子
-
#pragma mark 繪制圖層 -(void)drawMyLayer{CGSize size=[UIScreen mainScreen].bounds.size;//獲得根圖層layer=[[CALayer alloc]init];//設置背景顏色,由于QuartzCore是跨平臺框架,無法直接使用UIColorlayer.backgroundColor=[UIColor colorWithRed:0 green:146/255.0 blue:1.0 alpha:1.0].CGColor;//設置中心點layer.position=CGPointMake(size.width/2, size.height/2);//設置大小layer.bounds=CGRectMake(0, 0, WIDTH,WIDTH);//設置圓角,當圓角半徑等于矩形的一半時看起來就是一個圓形layer.cornerRadius=WIDTH/2;//設置陰影layer.shadowColor=[UIColor grayColor].CGColor;layer.shadowOffset=CGSizeMake(2, 2);layer.shadowOpacity=.9;//設置邊框// layer.borderColor=[UIColor whiteColor].CGColor;// layer.borderWidth=1;//設置錨點// layer.anchorPoint=CGPointZero; [self.view.layer addSublayer:layer]; } #pragma mark 點擊放大 -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{UITouch *touch=[touches anyObject];CGFloat width=layer.bounds.size.width;if (width==WIDTH) {width=WIDTH*4;}else{width=WIDTH;}layer.bounds=CGRectMake(0, 0, width, width);layer.position=[touch locationInView:self.view];layer.cornerRadius=width/2; }
七、CALayer繪圖
使用Quartz 2D繪圖,是直接調用UIView的drawRect:方法繪制圖形、圖像,這種方式的本質還是再圖層中繪制。drawRect:方法是由UIKit組件進行調用,因此厘米那可以使用到一些UIKir封裝的方法進行繪制,而直接繪制到圖層的方法由于并非UIKit直接調用因此只能用原生的Core Graphics方法繪制;?
圖層繪制有兩種方法,不管使用那種方法繪制完必須調用圖層的setNeedDisplay方法,下面介紹圖層的兩種繪制方法:
(1)、通過圖層代理drawLayer:inContext:方法繪制
通過代理方法進行圖層呢個繪制只要指定圖層的代理,然后在代理對象中重寫 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;方法即可。需要注意這個方法雖然是代理方法但是不用手動實習那CALayerDelegate,因為CALayer定義中給NSObject做了分類擴展,所有的NSObject都包含這個方法。另外設置完代理后必須要調用圖層的 - (void)setNeedsDisplay;方法,否測繪制內容無法顯示;?
例如:
#pragma mark 繪制圖層 -(void)drawMyLayer{//自定義圖層CALayer *layer=[[CALayer alloc]init];layer.bounds=CGRectMake(0, 0, PHOTO_HEIGHT, PHOTO_HEIGHT);layer.position=CGPointMake(160, 200);layer.backgroundColor=[UIColor redColor].CGColor;layer.cornerRadius=PHOTO_HEIGHT/2;//注意僅僅設置圓角,對于圖形而言可以正常顯示,但是對于圖層中繪制的圖片無法正確顯示//如果想要正確顯示則必須設置masksToBounds=YES,剪切子圖層layer.masksToBounds=YES;//陰影效果無法和masksToBounds同時使用,因為masksToBounds的目的就是剪切外邊框,//而陰影效果剛好在外邊框// layer.shadowColor=[UIColor grayColor].CGColor;// layer.shadowOffset=CGSizeMake(2, 2);// layer.shadowOpacity=1;//設置邊框layer.borderColor=[UIColor whiteColor].CGColor;layer.borderWidth=2;//設置圖層代理layer.delegate=self;//添加圖層到根圖層 [self.view.layer addSublayer:layer];//調用圖層setNeedDisplay,否則代理方法不會被調用 [layer setNeedsDisplay]; } #pragma mark 繪制圖形、圖像到圖層,注意參數中的ctx是圖層的圖形上下文,其中繪圖位置也是相對圖層而言的 -(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{// NSLog(@"%@",layer);//這個圖層正是上面定義的圖層 CGContextSaveGState(ctx);//圖形上下文形變,解決圖片倒立的問題CGContextScaleCTM(ctx, 1, -1);CGContextTranslateCTM(ctx, 0, -PHOTO_HEIGHT);UIImage *image=[UIImage imageNamed:@"001.png"];//注意這個位置是相對于圖層而言的不是屏幕CGContextDrawImage(ctx, CGRectMake(0, 0, PHOTO_HEIGHT, PHOTO_HEIGHT), image.CGImage);// CGContextFillRect(ctx, CGRectMake(0, 0, 100, 100));// CGContextDrawPath(ctx, kCGPathFillStroke); CGContextRestoreGState(ctx); }
(2)、使用自定義圖層繪圖
在自定義圖層繪圖時只要自己編寫一個類繼承與CALayer然后在 - (void)drawInContext:(CGContextRef)ctx;中繪圖即可。同前面在代理方法繪圖一樣,要顯示圖層中繪制的內容也要調用圖層的 - (void)setNeedsDisplay;方法,否則 - (void)drawInContext:(CGContextRef)ctx;方法將不會調用;?
例如:?
KCALayer.h #import "KCALayer.h"@implementation KCALayer -(void)drawInContext:(CGContextRef)ctx{NSLog(@"3-drawInContext:");NSLog(@"CGContext:%@",ctx);// CGContextRotateCTM(ctx, M_PI_4);CGContextSetRGBFillColor(ctx, 135.0/255.0, 232.0/255.0, 84.0/255.0, 1);CGContextSetRGBStrokeColor(ctx, 135.0/255.0, 232.0/255.0, 84.0/255.0, 1);// CGContextFillRect(ctx, CGRectMake(0, 0, 100, 100));// CGContextFillEllipseInRect(ctx, CGRectMake(50, 50, 100, 100));CGContextMoveToPoint(ctx, 94.5, 33.5);//// Star DrawingCGContextAddLineToPoint(ctx,104.02, 47.39);CGContextAddLineToPoint(ctx,120.18, 52.16);CGContextAddLineToPoint(ctx,109.91, 65.51);CGContextAddLineToPoint(ctx,110.37, 82.34);CGContextAddLineToPoint(ctx,94.5, 76.7);CGContextAddLineToPoint(ctx,78.63, 82.34);CGContextAddLineToPoint(ctx,79.09, 65.51);CGContextAddLineToPoint(ctx,68.82, 52.16);CGContextAddLineToPoint(ctx,84.98, 47.39);CGContextClosePath(ctx);CGContextDrawPath(ctx, kCGPathFillStroke); } @end
ViewController.m #pragma mark 繪制圖層 -(void)drawMyLayer{KCALayer *layer=[[KCALayer alloc]init];layer.bounds=CGRectMake(0, 0, 185, 185);layer.position=CGPointMake(160,284);layer.backgroundColor=[UIColor colorWithRed:0 green:146/255.0 blue:1.0 alpha:1.0].CGColor;//顯示圖層 [layer setNeedsDisplay];[self.view.layer addSublayer:layer]; }
?
七、CALayer繪圖
使用Quartz 2D繪圖,是直接調用UIView的drawRect:方法繪制圖形、圖像,這種方式的本質還是再圖層中繪制。drawRect:方法是由UIKit組件進行調用,因此厘米那可以使用到一些UIKir封裝的方法進行繪制,而直接繪制到圖層的方法由于并非UIKit直接調用因此只能用原生的Core Graphics方法繪制;?
圖層繪制有兩種方法,不管使用那種方法繪制完必須調用圖層的setNeedDisplay方法,下面介紹圖層的兩種繪制方法:
(1)、通過圖層代理drawLayer:inContext:方法繪制
通過代理方法進行圖層呢個繪制只要指定圖層的代理,然后在代理對象中重寫 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;方法即可。需要注意這個方法雖然是代理方法但是不用手動實習那CALayerDelegate,因為CALayer定義中給NSObject做了分類擴展,所有的NSObject都包含這個方法。另外設置完代理后必須要調用圖層的 - (void)setNeedsDisplay;方法,否測繪制內容無法顯示;?
例如: