CAlayer層的屬性
一、position和anchorPoint
1.簡單介紹
CALayer有2個非常重要的屬性:position和anchorPoint
@property CGPoint position;
用來設置CALayer在父層中的位置
以父層的左上角為原點(0, 0)
@property CGPoint anchorPoint;
稱為“定位點”、“錨點”
決定著CALayer身上的哪個點會在position屬性所指的位置
以自己的左上角為原點(0, 0)
它的x、y取值范圍都是0~1,默認值為(0.5, 0.5)
2.圖示
anchorPoint
它的取值為0~1
紅色圖層的anchorPoint為(0,0)
紅色圖層的anchorPoint為(0.5,0.5)
紅色圖層的anchorPoint為(1,1)
紅色圖層的anchorPoint為(0.5,0)
position和anchorPoint
添加一個紅色圖層到綠色圖層上,紅色圖層顯示到什么位置,由position屬性決定
假設紅色圖層的position是(100,100)
到底把紅色圖層的哪個點移動到(100,100)的坐標位置,錨點。
紅色圖層的錨點是(0,0)
紅色圖層的錨點是(0.5,0.5)
紅色圖層的錨點是(1,1)
紅色圖層的錨點是(0.5,0)
3.代碼示例
(1)沒有設置錨點。默認的錨點位置為(0.5,0.5)
#import "YYViewController.h"
@interface YYViewController ()
@end
- (void)viewDidLoad
{
[super viewDidLoad];
//創建圖層
CALayer *layer=[CALayer layer];
//設置圖層的屬性
layer.backgroundColor=[UIColor redColor].CGColor;
layer.bounds=CGRectMake(0, 0, 100, 100);
//添加圖層
[self.view.layer addSublayer:layer];
}
@end
(1)設置錨點位置為(0,0)
二、隱式動畫
1.簡單說明
每一個UIView內部都默認關聯著一個CALayer,我們可用稱這個Layer為Root Layer(根層)
所有的非Root Layer,也就是手動創建的CALayer對象,都存在著隱式動畫
什么是隱式動畫?
當對非Root Layer的部分屬性進行修改時,默認會自動產生一些動畫效果
而這些屬性稱為Animatable Properties(可動畫屬性)
列舉幾個常見的Animatable Properties:
bounds:用于設置CALayer的寬度和高度。修改這個屬性會產生縮放動畫
backgroundColor:用于設置CALayer的背景色。修改這個屬性會產生背景色的漸變動畫
position:用于設置CALayer的位置。修改這個屬性會產生平移動畫
2.代碼示例
#import "YYViewController.h"
@interface YYViewController ()
@property(nonatomic,strong)CALayer *layer;
@end
- (void)viewDidLoad
{
[super viewDidLoad];
//創建圖層
CALayer *mylayer=[CALayer layer];
//設置圖層屬性
mylayer.backgroundColor=[UIColor brownColor].CGColor;
mylayer.bounds=CGRectMake(0, 0, 150, 100);
//顯示位置
mylayer.position=CGPointMake(100, 100);
mylayer.anchorPoint=CGPointZero;
mylayer.cornerRadius=20;
//添加圖層
[self.view.layer addSublayer:mylayer];
self.layer=mylayer;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//隱式動畫
self.layer.bounds=CGRectMake(0, 0, 200, 60);
self.layer.backgroundColor=[UIColor yellowColor].CGColor;
}
@end
關閉隱式動畫:
可以查看頭文件,看有沒有Animatable,如果有則表示支持。
也可以查看官方文檔
文檔中標明的這些屬性都是支持隱式動畫的
自定義layer
一、第一種方式
1.簡單說明
以前想要在view中畫東西,需要自定義view,創建一個類與之關聯,讓這個類繼承自UIView,然后重寫它的DrawRect:方法,然后在該方法中畫圖。
繪制圖形的步驟:
(1)獲取上下文
(2)繪制圖形
(3)渲染圖形
如果在layer上畫東西,與上面的過程類似。
代碼示例:
新建一個類,讓該類繼承自CALayer
YYMylayer.m文件
#import "YYMylayer.h"
@implementation YYMylayer
//重寫該方法,在該方法內繪制圖形
-(void)drawInContext:(CGContextRef)ctx
{
//1.繪制圖形
//畫一個圓
CGContextAddEllipseInRect(ctx, CGRectMake(50, 50, 100, 100));
//設置屬性(顏色)
// [[UIColor yellowColor]set];
CGContextSetRGBFillColor(ctx, 0, 0, 1, 1);
//2.渲染
CGContextFillPath(ctx);
}
@end
#import "YYViewController.h"
#import "YYMylayer.h"
@interface YYViewController ()
@end
- (void)viewDidLoad
{
[super viewDidLoad];
//1.創建自定義的layer
YYMylayer *layer=[YYMylayer layer];
//2.設置layer的屬性
layer.backgroundColor=[UIColor brownColor].CGColor;
layer.bounds=CGRectMake(0, 0, 200, 150);
layer.anchorPoint=CGPointZero;
layer.position=CGPointMake(100, 100);
layer.cornerRadius=20;
layer.shadowColor=[UIColor blackColor].CGColor;
layer.shadowOffset=CGSizeMake(10, 20);
layer.shadowOpacity=0.6;
[layer setNeedsDisplay];
//3.添加layer
[self.view.layer addSublayer:layer];
}
@end
2.拓展
UIView中繪圖說明
@implementation YYVIEW
- (void)drawRect:(CGRect)rect
{
//1.獲取上下文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//2.繪制圖形
CGContextAddEllipseInRect(ctx, CGRectMake(50, 50, 100, 100));
//設置屬性(顏色)
// [[UIColor yellowColor]set];
CGContextSetRGBFillColor(ctx, 0, 0, 1, 1);
//3.渲染
CGContextFillPath(ctx);
//在執行渲染操作的時候,本質上它的內部相當于調用了下面的方法
[self.layer drawInContext:ctx];
}
在執行渲染操作的時候,本質上它的內部相當于執行了 [self.layer drawInContext:ctx];
二、第二種方式
方法描述:設置CALayer的delegate,然后讓delegate實現drawLayer:inContext:方法,當CALayer需要繪圖時,會調用delegate的drawLayer:inContext:方法進行繪圖。
代碼示例:
#import "YYViewController.h"
@interface YYViewController ()
@end
- (void)viewDidLoad
{
[super viewDidLoad];
//1.創建自定義的layer
CALayer *layer=[CALayer layer];
//2.設置layer的屬性
layer.backgroundColor=[UIColor brownColor].CGColor;
layer.bounds=CGRectMake(0, 0, 200, 150);
layer.anchorPoint=CGPointZero;
layer.position=CGPointMake(100, 100);
layer.cornerRadius=20;
layer.shadowColor=[UIColor blackColor].CGColor;
layer.shadowOffset=CGSizeMake(10, 20);
layer.shadowOpacity=0.6;
//設置代理
layer.delegate=self;
[layer setNeedsDisplay];
//3.添加layer
[self.view.layer addSublayer:layer];
}
-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
//1.繪制圖形
//畫一個圓
CGContextAddEllipseInRect(ctx, CGRectMake(50, 50, 100, 100));
//設置屬性(顏色)
// [[UIColor yellowColor]set];
CGContextSetRGBFillColor(ctx, 0, 0, 1, 1);
//2.渲染
CGContextFillPath(ctx);
}
@end
注意點:不能再將某個UIView設置為CALayer的delegate,因為UIView對象已經是它內部根層的delegate,再次設置為其他層的delegate就會出問題。
在設置代理的時候,它并不要求我們遵守協議,說明這個方法是nsobject中的,就不需要再額外的顯示遵守協議了。
提示:以后如果要設置某個類的代理,但是這個代理沒要求我們遵守什么特定的協議,那么可以認為這個協議方法是NSObject里邊的。
三、補充說明
(1)無論采取哪種方法來自定義層,都必須調用CALayer的setNeedsDisplay方法才能正常繪圖。
(2)詳細現實過程:
當UIView需要顯示時,它內部的層會準備好一個CGContextRef(圖形上下文),然后調用delegate(這里就是UIView)的drawLayer:inContext:方法,并且傳入已經準備好的CGContextRef對象。而UIView在drawLayer:inContext:方法中又會調用自己的drawRect:方法。平時在drawRect:中通過UIGraphicsGetCurrentContext()獲取的就是由層傳入的CGContextRef對象,在drawRect:中完成的所有繪圖都會填入層的CGContextRef中,然后被拷貝至屏幕。
新聞熱點
疑難解答