iOS開發CoreAnimation解讀之二——對CALayer的分析

iOS開發CoreAnimation解讀之二——對CALayer的分析

1、UIView中的CALayer屬性

1.Layer專門負責view的視圖渲染

        每個UIView的對象中都有一個layer這樣的屬性,而且layer會負責view中有關圖形繪製的相關操做,例如咱們設置view的背景顏色和設置layer的背景顏色都是有效的,而且,設置view的背景色依然是經過layer來展現的,咱們能夠寫以下的測試代碼:數組

    UIView * view = [[UIView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    view.backgroundColor = [UIColor redColor];
    
    UIView * view2 = [[UIView alloc]initWithFrame:CGRectMake(100, 300, 100, 100)];
    view2.layer.backgroundColor = view.layer.backgroundColor;
    [self.view addSubview:view];
    [self.view addSubview:view2];

能夠看出,咱們設置view的backgroundColor屬性其實起做用的也是layer的backgroundColor。框架

2.自定義view默認layer屬性的類

        UIView是不少視圖類的父類,根據功能不一樣,會分出UIImageView,UIScrollerView,UITableView等,CALayer也類似,其也能夠根據功能分出許多子類,還能夠根據咱們的需求自定義一個Layer類。UIView其中的layer默認是CALyer類,咱們也能夠經過重寫View中的以下方法來使其建立咱們須要的layer類:ide

+(Class)layerClass{
}

例如咱們自定義一個View類,在自定義一個Layer類,是的自定義的View默認建立的layer是自定義的layer:函數

在MyView中重寫上述方法:測試

+(Class)layerClass{
    return [MyLayer  class];
}

在MyLayer中進行一些自定義:動畫

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.backgroundColor = [UIColor redColor].CGColor;
    }
    return self;
}

以後咱們使用這個MyView的對象時,layer層的背景色就是紅色的了。spa

2、幾種系統的Layer類

        前邊說過,和UIView類似,CALayer也很據功能衍生出許多子類,系統系統給咱們可使用的有以下幾種:代理

1.CAEmitterLayer

CoreAnimation框架中的CAEmitterLayer是一個粒子發射器系統,負責粒子的建立和發射源屬性。經過它,咱們能夠輕鬆建立出炫酷的粒子效果。rest

2.CAGradientLayer

CAGradientLayer能夠建立出色彩漸變的圖層效果,以下:code

3.CAEAGLLayer

CAEAGLLayer能夠經過OpenGL ES來進行界面的繪製。

4.CAReplicatorLayer

CAReplicatorLayer是一個layer容器,會對其中的subLayer進行復制和屬性偏移,經過它,能夠建立出相似倒影的效果,也能夠進行變換複製,以下:

5.CAScrollLayer

CAScrollLayer能夠支持其上管理的多個子層進行滑動,可是隻能經過代碼進行管理,不能進行用戶點按觸發。

6.CAShapeLayer

CAShapeLayer可讓咱們在layer層是直接繪製出自定義的形狀。

7.CATextLayer

CATextLayer能夠經過字符串進行文字的繪製。

8.CATiledLayer

CATiledLayer相似瓦片視圖,能夠將繪製分區域進行,經常使用於一張大的圖片的分不分繪製。

9.CATransformLayer

CATransformLayer用於構建一些3D效果的圖層。

3、設置與調整Layer層的內容

設置層的內容有下面三種方式:

1.能夠經過設置CGImage爲layer的內容。

2.能夠經過代理方法來動態修改或者繪製層的內容。

3.經過自定義CALayer對象來建立層的內容。

當你設置了Layer的內容後,例如設置了一張圖片,內容的尺寸不必定會恰好和layer的尺寸合適,咱們能夠對其位置的調整,使其達到咱們想要的效果,contentsGravity屬性決定了內容對齊與填充方式,它能夠分爲兩個方面:

1.不改變內容的原始大小

這種模式中不會改變內容的原始大小,若是層的尺寸小於內容的尺寸,則內容會被切割,若是層的尺寸大於內容的尺寸,多出的部分將會顯示層的背景顏色。下面的這些設置方式爲這種模式:

CA_EXTERN NSString * const kCAGravityCenter
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityTop
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityBottom
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityLeft
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityRight
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityTopLeft
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityTopRight
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityBottomLeft
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityBottomRight
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

每一個參數對應的對其模式以下圖:

2.改變內容的尺寸大小

這種模式設置的其實是一種填充方式,參數以下:

CA_EXTERN NSString * const kCAGravityResize
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityResizeAspect
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityResizeAspectFill
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

4、CALayer的接口應用總結

一、建立與初始化layer相關

//經過類方法建立並初始化一個layer
+ (instancetype)layer;
//初始化方法
- (instancetype)init;
//經過一個layer建立一個副本
- (instancetype)initWithLayer:(id)layer;

二、渲染層layer與模型層layer

    在CALayer中,有以下兩個屬性,他們都返回一個CALayer的對象:

//渲染層layer
- (nullable id)presentationLayer;
//模型層layer
- (id)modelLayer;

對於presentationLayer,這個屬性不必定總會返回一個實體對象,只有當進行動畫或者其餘渲染的操做時,這個屬性會返回一個在當前屏幕上的layer,不且每一次執行,這個對象都會不一樣,它是原layer的一個副本presentationLayer的modelLayer就是其實體layer層。

對於modelLayer,它會返回當前的存儲信息的Layer,也是當前的layer對象,始終惟一。

3.一些屬性與方法

+ (nullable id)defaultValueForKey:(NSString *)key;

 

上面這個屬性用於設置layer中默認屬性的值,咱們能夠在子類中重寫這個方法來改變默認建立的layer的一些屬性,例如以下代碼,咱們建立出來的layer就默認有紅色的背景顏色:

+(id)defaultValueForKey:(NSString *)key{
    if ([key isEqualToString:@"backgroundColor"]) {
        return (id)[UIColor redColor].CGColor;
    }
    return [super defaultValueForKey:key];
}
//這個方法也只使用在子類中重寫,用於設置在某些屬性改變時是否進行layer重繪
+ (BOOL)needsDisplayForKey:(NSString *)key;
//子類重寫這個方法設置屬性是否能夠被歸檔
- (BOOL)shouldArchiveValueForKey:(NSString *)key;
/*********************************************/
//設置layer尺寸
@property CGRect bounds;
//設置layer位置
@property CGPoint position;
//設置其在父layer中的層次,默認爲0,這個值越大,層次越靠上
@property CGFloat zPosition;
//錨點
@property CGPoint anchorPoint;
//在Z軸上的錨點位置 3D變換時會有很大影響
@property CGFloat anchorPointZ;
//進行3D變換
@property CATransform3D transform;
//獲取和設置CGAffineTransform變換
- (CGAffineTransform)affineTransform;
- (void)setAffineTransform:(CGAffineTransform)m;
//設置layer的frame
@property CGRect frame;
//設置是否隱藏
@property(getter=isHidden) BOOL hidden;
//每一個layer層有兩面,這個屬性肯定是否兩面都顯示
@property(getter=isDoubleSided) BOOL doubleSided;
//是否進行y軸的方向翻轉
@property(getter=isGeometryFlipped) BOOL geometryFlipped;
//獲取當前layer內容y軸方向是否被翻轉了
- (BOOL)contentsAreFlipped;
//父layer視圖
@property(nullable, readonly) CALayer *superlayer;
//從其父layer層上移除
- (void)removeFromSuperlayer;
//全部子layer數組
@property(nullable, copy) NSArray<CALayer *> *sublayers;
//添加一個字layer
- (void)addSublayer:(CALayer *)layer;
//插入一個子layer
- (void)insertSublayer:(CALayer *)layer atIndex:(unsigned)idx;
//將一個子layer插入到最下面
- (void)insertSublayer:(CALayer *)layer below:(nullable CALayer *)sibling;
//將一個子layer插入到最上面
- (void)insertSublayer:(CALayer *)layer above:(nullable CALayer *)sibling;
//替換一個子layer
- (void)replaceSublayer:(CALayer *)layer with:(CALayer *)layer2;
//對其子layer進行3D變換
@property CATransform3D sublayerTransform;
//遮罩層layer
@property(nullable, strong) CALayer *mask;
//舍否進行bounds的切割,在設置圓角屬性時會設置爲YES
@property BOOL masksToBounds;
//下面這些方法用於座標轉換
- (CGPoint)convertPoint:(CGPoint)p fromLayer:(nullable CALayer *)l;
- (CGPoint)convertPoint:(CGPoint)p toLayer:(nullable CALayer *)l;
- (CGRect)convertRect:(CGRect)r fromLayer:(nullable CALayer *)l;
- (CGRect)convertRect:(CGRect)r toLayer:(nullable CALayer *)l;
//返回包含某一點的最上層的子layer
- (nullable CALayer *)hitTest:(CGPoint)p;
//返回layer的bounds內是否包含某一點
- (BOOL)containsPoint:(CGPoint)p;
//設置layer的內容,通常會設置爲CGImage的對象
@property(nullable, strong) id contents;
//獲取內容的rect尺寸
@property CGRect contentsRect;
//設置內容的填充和對其方式,具體上面有說
@property(copy) NSString *contentsGravity;
//設置內容的縮放
@property CGFloat contentsScale;

下面這個屬性和內容拉伸相關:

@property CGRect contentsCenter;

這個屬性肯定一個矩形區域,當內容進行拉伸或者縮放的時候,這一部分的區域是會被形變的,例如默認設置爲(0,0,1,1),則整個內容區域都會參與形變。若是咱們設置爲(0.25,0.25,0.5,0.5),那麼只有中間0.5*0.5比例寬高的區域會被拉伸,四周都不會。

下面這兩個屬性用來設置縮放或拉伸的模式:

//設置縮小的模式
@property(copy) NSString *minificationFilter;
//設置放大的模式
@property(copy) NSString *magnificationFilter;
//縮放因子
@property float minificationFilterBias;
//模式參數以下
//臨近插值
NSString * const kCAFilterNearest;
//線性拉伸
NSString * const kCAFilterLinear;
//瓦片複製拉伸
NSString * const kCAFilterTrilinear;
//設置內容是否徹底不透明
@property(getter=isOpaque) BOOL opaque;
//從新加載繪製內容
- (void)display;
//設置內容爲須要從新繪製
- (void)setNeedsDisplay;
//設置某一區域內容須要從新繪製
- (void)setNeedsDisplayInRect:(CGRect)r;
//獲取是否須要從新繪製
- (BOOL)needsDisplay;
//若是須要,進行內容重繪
- (void)displayIfNeeded;
//這個屬性設置爲YES,當內容改變時會自動調用- (void)setNeedsDisplay函數
@property BOOL needsDisplayOnBoundsChange;
//繪製與讀取內容
- (void)drawInContext:(CGContextRef)ctx;
- (void)renderInContext:(CGContextRef)ctx;
//設置背景顏色
@property(nullable) CGColorRef backgroundColor;
//設置圓角半徑
@property CGFloat cornerRadius;
//設置邊框寬度
@property CGFloat borderWidth;
//設置邊框顏色
@property(nullable) CGColorRef borderColor;
//設置透明度
@property float opacity;
//設置陰影顏色
@property(nullable) CGColorRef shadowColor;
//設置陰影透明度
@property float shadowOpacity;
//設置陰影偏移量
@property CGSize shadowOffset;
//設置陰影圓角半徑
@property CGFloat shadowRadius;
//設置陰影路徑
@property(nullable) CGPathRef shadowPath;
//添加一個動畫對象 key值起到id的做用,經過key值,能夠取到這個動畫對象
- (void)addAnimation:(CAAnimation *)anim forKey:(nullable NSString *)key;
//移除全部動畫對象
- (void)removeAllAnimations;
//移除某個動畫對象
- (void)removeAnimationForKey:(NSString *)key;
//獲取全部動畫對象的key值
- (nullable NSArray<NSString *> *)animationKeys;
//經過key值獲取動畫對象
- (nullable CAAnimation *)animationForKey:(NSString *)key;

專一技術,熱愛生活,交流技術,也作朋友。

——琿少 QQ羣:203317592

相關文章
相關標籤/搜索