1. UIView 中沒有暴露出來的CALayer的功能:
陰影养泡,圓角躺率,帶顏色的邊框
3D變換
非矩形范圍
透明遮罩
多級非線性動畫
CALayer 沒有善茎,UIView有的功能:
對CALayer進(jìn)行了初步封裝晌涕,調(diào)用時較便捷
UIView可以使用自動布局自適應(yīng)
2.使用CA需要引入庫:QuartzCore到buildPhases中
3.contents屬性
你真正要賦值的類型應(yīng)該是CGImageRef栈顷,它是一個指向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屬性允許我們在圖層邊框里顯示寄宿圖的一個子域
它使用了單位坐標(biāo)。在app中最有趣的地方在于一個叫做image sprites(圖片拼合)的
用法鸵鸥。圖片拼合后可以打包整合到一張大圖上一次性載入奠滑。相比多次載入不同的
圖片,這樣做能夠帶來很多方面的好處:內(nèi)存使用妒穴,載入時間宋税,渲染性能等等。
6.contentsCenter
contentsCenter其實是一個CGRect讼油,它定義了一個固定的邊框和一個在圖
層上可拉伸的區(qū)域杰赛。他工作起來的效果和UIImage里的-resizableImageWithCapInsets:方法效果非常類似,只是它可以運用
到任何寄宿圖矮台,甚至包括在Core Graphics運行時繪制的圖形
在XIB中可以使用Stretching
7.不同于UIView乏屯,當(dāng)圖層顯示在屏幕上時,CALayer不會自動重繪它的內(nèi)容瘦赫。它把重繪的決定權(quán)交給了開發(fā)者辰晕。
在UIView時,當(dāng)使用寄宿了視圖的圖層的時候耸彪,你也不必實現(xiàn)-displayLayer:和-方法來繪制你的寄宿圖伞芹。通常做法是實現(xiàn)UIView的-方法,UIView就會幫你做完剩下的工作,包括在需要重繪的時候調(diào)用方法唱较。
8.對于視圖或者圖層來說扎唾,并不是一個非常清晰的屬性,它其實是一個虛擬屬性南缓,是根據(jù)bounds胸遇,和transform計算而來,所以當(dāng)其中任何一個值發(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點種方向侦高。
9.zPostion屬性在大多數(shù)情況下其實并不常用,可以用于在三維空間移動和旋轉(zhuǎn)圖層做變換嫉柴,此外, 最實用的功能就是改變圖層的顯示順序了奉呛。在zPostion计螺,越大的越優(yōu)先顯示。不過其不能改變事件傳遞的順序
10.圓角
一般使用layer.cornerRadius和masksToBounds侧馅,對全部角設(shè)置為圓角并裁剪子視圖危尿。
如果設(shè)置有些圓角有些直角,需要使用圖層蒙板或是CAShapeLayer
11.陰影往往可以達(dá)到圖層深度暗示的效果馁痴。也能夠用來強調(diào)正在顯示的圖層和優(yōu)先級。shadowOpacity是一個單位屬性肺孤,設(shè)置一個大于0對值罗晕,陰影就可以顯示在任何圖層之下。shadowOpacity是一個必須在0.0(不可見)和1.0(完全不透明)之間的浮點數(shù)赠堵。想定制陰影小渊,可以使用CAlayer的三個屬性:shadowColor,shadowOffset茫叭,shadowRadius
shadowColor是CGColorRef類型
shadowOffset控制著陰影的方向和距離酬屉。它是一個CGSize值,寬度控制著陰影的橫向的位移,高度控制著縱向的位移呐萨。shadowOffset默認(rèn)是{0杀饵,-3},即隱形相對于Y軸有3個點點向上位移谬擦。
shadowRadius控制陰影的模糊度切距,當(dāng)它點值時0的時候,陰影就和視圖一樣有一個非常明確的邊界線惨远。當(dāng)值越來越大的時候谜悟,邊界線看上去越來越模糊。
陰影繼承自內(nèi)容的外形北秽,會連區(qū)域外的子視圖的邊界一起做陰影葡幸。
陰影非常耗資源,尤其有多個子圖層贺氓,還有透明效果的寄宿圖的時候蔚叨。如果知道隱形形狀時什么樣子,可以制定一個shadowPath來提高性能掠归。其時一個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ù)雜一點的圖形缅叠,UIBezierPath類會更合適
12.CALayer有一個屬性叫做mask.這個屬性本身就是個CALayer類型,有和其他圖層一樣的繪制和布局屬性虏冻。它類似于一個子圖層肤粱,相對于父圖層(即擁有該屬性的圖層)布局,但是它卻不是一個普通的子圖層厨相。不同于那些繪制在父圖層中的子圖層领曼,mask圖層定義了父圖層的部分可見區(qū)域。
mask屬性就像是一個餅干切割機蛮穿,mask圖層實心的部分會被保留下來庶骄,其他的則會被拋棄。
如果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屬性羔飞,這意味著你的蒙板可以通過代碼甚至是動畫實時生成。
13.當(dāng)我們視圖顯示一個圖片的時候檐春,都應(yīng)該正確地顯示這個圖片.原因如下:
能夠顯示最好的畫質(zhì)逻淌,像素既沒有被壓縮也沒有被拉伸。
能更好的使用內(nèi)存疟暖,因為這就是所有你要存儲的東西卡儒。
最好的性能表現(xiàn)田柔,CPU不需要為此額外的計算。
14.UIView的transform是CGAffineTransform類型骨望,用于二維空間做旋轉(zhuǎn)硬爆,縮放和平移
如下幾個函數(shù)都創(chuàng)建了一個CGAffineTransform實例:
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ù)可以在一個變換的基礎(chǔ)上做更深層次的變換,如果做一個既要縮放又要旋轉(zhuǎn)的變換锦募,這就會非常有用了摆屯。例如下面幾個函數(shù):
CGAffineTransformRotate(CGAffineTransform t,CGFloat angle)
CGAffineTransformScals(CGAffineTransform t, CGFloat sx, CGFloat sy)
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)
當(dāng)操縱一個變換的時候,初始生成一個什么都不做的變換很重要--也就是創(chuàng)建一個CGAffineTransform類型的空值糠亩,矩陣論中稱作單位矩陣虐骑,Core Graphics同樣也提供了一個方便的常量:
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)多出了一個z參數(shù)颠黎,并且旋轉(zhuǎn)函數(shù)除了angle之外多出了x,y,z三個參數(shù),分別決定了每個坐標(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的透視效果通過一個矩陣中一個很簡單的元素來控制:m34滞项。m34(圖5.9)用于按比例縮放X和Y的值來計算到底要離視角多遠(yuǎn)狭归。m34的默認(rèn)值是0,我們可以通過設(shè)置m34為-1.0 /d來應(yīng)用透視效果文判,d代表了想象中視角相機和屏幕之間的距離过椎,以像素為單位
CALayer有一個屬性叫做sublayerTransform。它也是CATransform3D類型戏仓,但和對一個圖層的變換不同疚宇,它影響到所有的子圖層。這意味著你可以一次性對包含這些圖層的容器做變換赏殃,于是所有的子圖層都自動繼承了這個變換方法敷待。
@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有一個叫做doubleSided的屬性來控制圖層的背面是否要被繪制。這是一個BOOL類型仁热,默認(rèn)為YES榜揖,如果設(shè)置為NO,那么當(dāng)圖層正面從相機視角消失的時候抗蠢,它將不會被繪制根盒。
盡管Core Animation圖層存在于3D空間之內(nèi),但它們并不都存在同一個3D空間物蝙。每個圖層的3D場景其實是扁平化的,當(dāng)你從正面觀察一個圖層敢艰,看到的實際上由子圖層創(chuàng)建的想象出來的3D場景诬乞,但當(dāng)你傾斜這個圖層,你會發(fā)現(xiàn)實際上這個3D場景僅僅是被繪制在圖層的表面。