IOS CALayer的屬性和使用
一、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是跨平臺框架,無法直接使用UIColor layer.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 Drawing CGContextAddLineToPoint(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;方法,否測繪製內容無法顯示;
例如: