Core Animation小記(一)

1. UIView 中沒有暴露出來的CALayer的功能:

陰影,圓角,帶顏色的邊框

3D變換

非矩形范圍

透明遮罩

多級非線性動畫

CALayer 沒有,UIView有的功能:

對CALayer進(jìn)行了初步封裝,調(diào)用時(shí)較便捷

UIView可以使用自動布局自適應(yīng)


2.使用CA需要引入庫:QuartzCore到buildPhases中

3.contents屬性

你真正要賦值的類型應(yīng)該是CGImageRef,它是一個(gè)指向CGImage結(jié)構(gòu)的指針

layer.contents = (__bridge id)image.CGImage

UIViewContentMode

typedef enum {

UIViewContentModeScaleToFill,

UIViewContentModeScaleAspectFit,??????// contents scaled to fit with fixed aspect. remainder is transparent

UIViewContentModeScaleAspectFill,???? // contents scaled to fill with fixed aspect. some portion of content may be clipped.

UIViewContentModeRedraw,??????????????// redraw on bounds change (calls -setNeedsDisplay)

UIViewContentModeCenter,??????????????// contents remain same size. positioned adjusted.

UIViewContentModeTop,

UIViewContentModeBottom,

UIViewContentModeLeft,

UIViewContentModeRight,

UIViewContentModeTopLeft,

UIViewContentModeTopRight,

UIViewContentModeBottomLeft,

UIViewContentModeBottomRight,

} UIViewContentMode;


CALayer與之對應(yīng)的為

UIViewContentModeScaleToFill -> (默認(rèn)效果)

UIViewContentModeScaleAspectFit -> kCAGravityResizeAspect

UIViewContentModeScaleAspectFill -> ?kCAGravityResizeAspectFill

4.UIView clipsToBounds ?maskToBounds

5.contentsRect

CALayer的contentsRect屬性允許我們在圖層邊框里顯示寄宿圖的一個(gè)子域

它使用了單位坐標(biāo)。在app中最有趣的地方在于一個(gè)叫做image sprites(圖片拼合)的

用法。圖片拼合后可以打包整合到一張大圖上一次性載入。相比多次載入不同的

圖片,這樣做能夠帶來很多方面的好處:內(nèi)存使用,載入時(shí)間,渲染性能等等。

6.contentsCenter

contentsCenter其實(shí)是一個(gè)CGRect,它定義了一個(gè)固定的邊框和一個(gè)在圖

層上可拉伸的區(qū)域。他工作起來的效果和UIImage里的-resizableImageWithCapInsets:方法效果非常類似,只是它可以運(yùn)用

到任何寄宿圖,甚至包括在Core Graphics運(yùn)行時(shí)繪制的圖形

在XIB中可以使用Stretching

7.不同于UIView,當(dāng)圖層顯示在屏幕上時(shí),CALayer不會自動重繪它的內(nèi)容。它把重繪的決定權(quán)交給了開發(fā)者。

在UIView時(shí),當(dāng)使用寄宿了視圖的圖層的時(shí)候,你也不必實(shí)現(xiàn)-displayLayer:和-方法來繪制你的寄宿圖。通常做法是實(shí)現(xiàn)UIView的-方法,UIView就會幫你做完剩下的工作,包括在需要重繪的時(shí)候調(diào)用方法。

8.對于視圖或者圖層來說,并不是一個(gè)非常清晰的屬性,它其實(shí)是一個(gè)虛擬屬性,是根據(jù)bounds,和transform計(jì)算而來,所以當(dāng)其中任何一個(gè)值發(fā)生改變,frame都會變化。相反,改變frame的值同樣會影響到他們當(dāng)中的值

視圖的center屬性和圖層的position屬性都指定了anchorPoint相對于父圖層的位置。圖層的anchorPoint通過position來控制它的frame位置,可以認(rèn)為anchorPoint是用來移動圖層的把柄

anchorPoint是單位坐標(biāo),指position與width,height的比例,(0.1,0.1)指position位于左10.30方向,(0.5,0.5)位于中心,(0.5,0.9)位于6點(diǎn)種方向。

9.zPostion屬性在大多數(shù)情況下其實(shí)并不常用,可以用于在三維空間移動和旋轉(zhuǎn)圖層做變換,此外, 最實(shí)用的功能就是改變圖層的顯示順序了。在zPostion,越大的越優(yōu)先顯示。不過其不能改變事件傳遞的順序

10.圓角

一般使用layer.cornerRadius和masksToBounds,對全部角設(shè)置為圓角并裁剪子視圖。

如果設(shè)置有些圓角有些直角,需要使用圖層蒙板或是CAShapeLayer

11.陰影往往可以達(dá)到圖層深度暗示的效果。也能夠用來強(qiáng)調(diào)正在顯示的圖層和優(yōu)先級。shadowOpacity是一個(gè)單位屬性,設(shè)置一個(gè)大于0對值,陰影就可以顯示在任何圖層之下。shadowOpacity是一個(gè)必須在0.0(不可見)和1.0(完全不透明)之間的浮點(diǎn)數(shù)。想定制陰影,可以使用CAlayer的三個(gè)屬性:shadowColor,shadowOffset,shadowRadius

shadowColor是CGColorRef類型

shadowOffset控制著陰影的方向和距離。它是一個(gè)CGSize值,寬度控制著陰影的橫向的位移,高度控制著縱向的位移。shadowOffset默認(rèn)是{0,-3},即隱形相對于Y軸有3個(gè)點(diǎn)點(diǎn)向上位移。

shadowRadius控制陰影的模糊度,當(dāng)它點(diǎn)值時(shí)0的時(shí)候,陰影就和視圖一樣有一個(gè)非常明確的邊界線。當(dāng)值越來越大的時(shí)候,邊界線看上去越來越模糊。

陰影繼承自內(nèi)容的外形,會連區(qū)域外的子視圖的邊界一起做陰影。

陰影非常耗資源,尤其有多個(gè)子圖層,還有透明效果的寄宿圖的時(shí)候。如果知道隱形形狀時(shí)什么樣子,可以制定一個(gè)shadowPath來提高性能。其時(shí)一個(gè)CGPathRef類型.

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIView *layerView1;

@property (nonatomic, weak) IBOutlet UIView *layerView2;

@end

@implementation ViewController

- (void)viewDidLoad

{

[super viewDidLoad];

//enable layer shadows

self.layerView1.layer.shadowOpacity = 0.5f;

self.layerView2.layer.shadowOpacity = 0.5f;

//create a square shadow

CGMutablePathRef squarePath = CGPathCreateMutable();

CGPathAddRect(squarePath, NULL, self.layerView1.bounds);

self.layerView1.layer.shadowPath = squarePath;

CGPathRelease(squarePath);

//create a circular shadow

CGMutablePathRef circlePath = CGPathCreateMutable();

CGPathAddEllipseInRect(circlePath, NULL, self.layerView2.bounds);

self.layerView2.layer.shadowPath = circlePath;

CGPathRelease(circlePath);

}

@end

但是如果是更加復(fù)雜一點(diǎn)的圖形,UIBezierPath類會更合適

12.CALayer有一個(gè)屬性叫做mask.這個(gè)屬性本身就是個(gè)CALayer類型,有和其他圖層一樣的繪制和布局屬性。它類似于一個(gè)子圖層,相對于父圖層(即擁有該屬性的圖層)布局,但是它卻不是一個(gè)普通的子圖層。不同于那些繪制在父圖層中的子圖層,mask圖層定義了父圖層的部分可見區(qū)域。

mask屬性就像是一個(gè)餅干切割機(jī),mask圖層實(shí)心的部分會被保留下來,其他的則會被拋棄。

如果mask圖層比父圖層要小,只有在mask圖層里面的內(nèi)容才是它關(guān)心的,除此以外的一切都會被隱藏起來。

@implementation ViewController

- (void)viewDidLoad

{

[super viewDidLoad];

//create mask layer

CALayer *maskLayer = [CALayer layer];

maskLayer.frame = self.layerView.bounds;

UIImage *maskImage = [UIImage imageNamed:@"Cone.png"];

maskLayer.contents = (__bridge id)maskImage.CGImage;

//apply mask to image layer

self.imageView.layer.mask = maskLayer;

}

@end

CALayer蒙板圖層真正厲害的地方在于蒙板圖不局限于靜態(tài)圖。任何有圖層構(gòu)成的都可以作為mask屬性,這意味著你的蒙板可以通過代碼甚至是動畫實(shí)時(shí)生成。

13.當(dāng)我們視圖顯示一個(gè)圖片的時(shí)候,都應(yīng)該正確地顯示這個(gè)圖片.原因如下:

能夠顯示最好的畫質(zhì),像素既沒有被壓縮也沒有被拉伸。

能更好的使用內(nèi)存,因?yàn)檫@就是所有你要存儲的東西。

最好的性能表現(xiàn),CPU不需要為此額外的計(jì)算。

14.UIView的transform是CGAffineTransform類型,用于二維空間做旋轉(zhuǎn),縮放和平移

如下幾個(gè)函數(shù)都創(chuàng)建了一個(gè)CGAffineTransform實(shí)例:

CGAffineTransformMakeRotation(CGFloat angle) 旋轉(zhuǎn)

CGAffineTransformMakeScale(CGFloat sx, CGFloat sy) 縮放

CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty) 平移

UIView的transform對應(yīng)于CALayer的affineTransform

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIView *layerView;

@end

@implementation ViewController

- (void)viewDidLoad

{

? ? ? ?[super viewDidLoad];

//rotate the layer 45 degrees

CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI_4);

self.layerView.layer.affineTransform = transform;

}

@end

Core Graphics提供了一系列的函數(shù)可以在一個(gè)變換的基礎(chǔ)上做更深層次的變換,如果做一個(gè)既要縮放又要旋轉(zhuǎn)的變換,這就會非常有用了。例如下面幾個(gè)函數(shù):

CGAffineTransformRotate(CGAffineTransform t,CGFloat angle)

CGAffineTransformScals(CGAffineTransform t, CGFloat sx, CGFloat sy)

CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)

當(dāng)操縱一個(gè)變換的時(shí)候,初始生成一個(gè)什么都不做的變換很重要--也就是創(chuàng)建一個(gè)CGAffineTransform類型的空值,矩陣論中稱作單位矩陣,Core Graphics同樣也提供了一個(gè)方便的常量:

CGAffineTransformIdentity

變換的順序會影響最終的結(jié)果,也就是說旋轉(zhuǎn)之后的平移和平移之后的旋轉(zhuǎn)結(jié)果可能不同。

15.CALayer的transform是CATransform3D類型,可以讓圖層在3D空間內(nèi)移動或者旋轉(zhuǎn)

Core Animation提供了一系列的方法用來創(chuàng)建和組合CATransform3D類型的矩陣,和Core Graphics的函數(shù)類似,但是3D的平移和旋轉(zhuǎn)多出了一個(gè)z參數(shù),并且旋轉(zhuǎn)函數(shù)除了angle之外多出了x,y,z三個(gè)參數(shù),分別決定了每個(gè)坐標(biāo)軸方向上的旋轉(zhuǎn):

CATransform3DMakeRotation(CGFloat angle, CGFloat x, CGFloat y, CGFloat z)

CATransform3DMakeScale(CGFloat sx, CGFloat sy, CGFloat sz)

CATransform3DMakeTranslation(Gloat tx, CGFloat ty, CGFloat tz)

CATransform3D的透視效果通過一個(gè)矩陣中一個(gè)很簡單的元素來控制:m34。m34(圖5.9)用于按比例縮放X和Y的值來計(jì)算到底要離視角多遠(yuǎn)。m34的默認(rèn)值是0,我們可以通過設(shè)置m34為-1.0 /d來應(yīng)用透視效果,d代表了想象中視角相機(jī)和屏幕之間的距離,以像素為單位

CALayer有一個(gè)屬性叫做sublayerTransform。它也是CATransform3D類型,但和對一個(gè)圖層的變換不同,它影響到所有的子圖層。這意味著你可以一次性對包含這些圖層的容器做變換,于是所有的子圖層都自動繼承了這個(gè)變換方法。

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIView *containerView;

@property (nonatomic, weak) IBOutlet UIView *layerView1;

@property (nonatomic, weak) IBOutlet UIView *layerView2;

@end

@implementation ViewController

- (void)viewDidLoad

{

[super viewDidLoad];

//apply perspective transform to container

CATransform3D perspective = CATransform3DIdentity;

perspective.m34 = - 1.0 / 500.0;

self.containerView.layer.sublayerTransform = perspective;

//rotate layerView1 by 45 degrees along the Y axis

CATransform3D transform1 = CATransform3DMakeRotation(M_PI_4, 0, 1, 0);

self.layerView1.layer.transform = transform1;

//rotate layerView2 by 45 degrees along the Y axis

CATransform3D transform2 = CATransform3DMakeRotation(-M_PI_4, 0, 1, 0);

self.layerView2.layer.transform = transform2;

}

CALayer有一個(gè)叫做doubleSided的屬性來控制圖層的背面是否要被繪制。這是一個(gè)BOOL類型,默認(rèn)為YES,如果設(shè)置為NO,那么當(dāng)圖層正面從相機(jī)視角消失的時(shí)候,它將不會被繪制。

盡管Core Animation圖層存在于3D空間之內(nèi),但它們并不都存在同一個(gè)3D空間。每個(gè)圖層的3D場景其實(shí)是扁平化的,當(dāng)你從正面觀察一個(gè)圖層,看到的實(shí)際上由子圖層創(chuàng)建的想象出來的3D場景,但當(dāng)你傾斜這個(gè)圖層,你會發(fā)現(xiàn)實(shí)際上這個(gè)3D場景僅僅是被繪制在圖層的表面。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Core Animation其實(shí)是一個(gè)令人誤解的命名。你可能認(rèn)為它只是用來做動畫的,但實(shí)際上它是從一個(gè)叫做Laye...
    小貓仔閱讀 3,950評論 1 4
  • 書寫的很好,翻譯的也棒!感謝譯者,感謝感謝! iOS-Core-Animation-Advanced-Techni...
    錢噓噓閱讀 2,427評論 0 6
  • 在iOS中隨處都可以看到絢麗的動畫效果,實(shí)現(xiàn)這些動畫的過程并不復(fù)雜,今天將帶大家一窺ios動畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,686評論 6 30
  • 在iOS中隨處都可以看到絢麗的動畫效果,實(shí)現(xiàn)這些動畫的過程并不復(fù)雜,今天將帶大家一窺iOS動畫全貌。在這里你可以看...
    F麥子閱讀 5,258評論 5 13
  • 轉(zhuǎn)載:http://www.itdecent.cn/p/32fcadd12108 每個(gè)UIView有一個(gè)伙伴稱為l...
    F麥子閱讀 6,567評論 0 13

友情鏈接更多精彩內(nèi)容