CALayer簡(jiǎn)介
CALayer(圖層)通常用于存儲(chǔ)和管理UIView(視圖)的視覺內(nèi)容(比如背景顏色、邊框和陰影)囚玫,創(chuàng)建的UIView會(huì)持有一個(gè)從不為nil的layer屬性,可以用來訪問UIView的CALayer事镣,也就是UIView顯示的視覺內(nèi)容實(shí)際上是有CALayer來呈現(xiàn)的诲锹。但由于CALayer不能與用戶進(jìn)行交互状囱,但是UIView可以,所以這兩個(gè)對(duì)象更像明確的劃分了功能旭蠕,CALayer呈現(xiàn)視覺內(nèi)容停团,UIView響應(yīng)事件旷坦。
CALayer除了管理呈現(xiàn)的視覺內(nèi)容之外,還維護(hù)用于在屏幕上顯示的視覺內(nèi)容的相關(guān)的幾何形狀信息(如position(位置)佑稠、大小(size)和轉(zhuǎn)換(transform))秒梅。可以使用修改CALayer的視覺內(nèi)容相關(guān)屬性或幾何形狀信息相關(guān)屬性來啟動(dòng)動(dòng)畫舌胶,CALayer對(duì)象通過定義CALayer計(jì)時(shí)信息的CAMediaTiming協(xié)議封裝CALayer及其動(dòng)畫的持續(xù)時(shí)間和速度捆蜀。
如果CALayer對(duì)象是由UIView創(chuàng)建的,則UIView通常會(huì)自動(dòng)將自身指定為CALayer的代理幔嫂,并且不應(yīng)更改該關(guān)系辆它。對(duì)于自己創(chuàng)建的在沒有視圖的情況下用于顯示內(nèi)容CALayer對(duì)象,可以為其指定代理對(duì)象婉烟。
CALayer的常用屬性
@property CGRect bounds;
屬性描述 :CALayer對(duì)象的邊界娩井,默認(rèn)為CGRectZero,可設(shè)置動(dòng)畫似袁。
@property CGPoint position;
屬性描述 :CALayer對(duì)象邊界矩形相對(duì)其父級(jí)層(superlayer)的定位點(diǎn)位置洞辣。默認(rèn)為CGPointZero£夹疲可設(shè)置動(dòng)畫扬霜。
@property CGPoint anchorPoint;
屬性描述 :定位CALayer對(duì)象邊界矩形的錨點(diǎn),可以做成動(dòng)畫而涉。使用單位坐標(biāo)空間指定此屬性的值著瓶。此屬性的默認(rèn)值為(0.5,0.5),它表示CALayer(圖層)對(duì)象邊界矩形的中心啼县。視圖的所有幾何操作都發(fā)生在指定的點(diǎn)上材原,例如對(duì)具有默認(rèn)錨點(diǎn)的圖層應(yīng)用旋轉(zhuǎn)變換會(huì)導(dǎo)致該圖層繞其中心旋轉(zhuǎn),將錨點(diǎn)更改為一個(gè)不同的位置將導(dǎo)致圖層圍繞新點(diǎn)旋轉(zhuǎn)季眷。
@property CGFloat zPosition;
屬性描述 :CALayer對(duì)象在Z軸上的位置余蟹,可設(shè)置動(dòng)畫,此屬性的默認(rèn)值為0子刮。更改此屬性的值將更改屏幕上各CALayer(圖層)對(duì)象的前到后順序威酒。與值較低的層相比,值較高的層在視覺上更靠近查看器挺峡。這會(huì)影響框架矩形重疊的CALayer(圖層)對(duì)象的可見性葵孤。
cell = [tableView dequeueReusableCellWithIdentifier:YSCUserCenterTitleCellReuseIdentifier];
cell.layer.zPosition = 10;
可以讓上部的cell中設(shè)置背景的視圖底部約束超出cell橱赠,但在沒有設(shè)置zPosition屬性時(shí)尤仍,可能是這樣的:
@property(getter=isHidden) BOOL hidden;
屬性描述 :隱藏CALayer對(duì)象及其子層(sublayer),如果為true狭姨,則不顯示CALayer對(duì)象及其子層(sublayer)宰啦。默認(rèn)為“ NO”鲤嫡,可設(shè)置動(dòng)畫。
@property(nullable, readonly) CALayer *superlayer;
屬性描述:調(diào)用方的superlayer(父級(jí)層)對(duì)象绑莺。隱式更改以匹配“sublayers”屬性描述的層次結(jié)構(gòu)暖眼。
@property BOOL masksToBounds;
屬性描述 : 一個(gè)布爾值,指示CALayer對(duì)象的子層(sublayers)超出邊界的部分是否將剪裁纺裁,可設(shè)置動(dòng)畫诫肠。
@property(nullable, strong) id contents;
屬性描述 :提供圖層內(nèi)容的對(duì)象,可設(shè)置動(dòng)畫欺缘,此屬性的默認(rèn)值為nil栋豫。如果使用CALayer對(duì)象來顯示靜態(tài)圖像,可以將此屬性設(shè)置為包含想要顯示的圖像的CGImageRef對(duì)象谚殊。如果CALayer對(duì)象綁定到一個(gè)視圖對(duì)象丧鸯,則應(yīng)該避免直接設(shè)置這個(gè)屬性的內(nèi)容,因?yàn)橐晥D和圖層之間的相互作用通常會(huì)導(dǎo)致視圖在隨后的更新中替換該屬性的內(nèi)容嫩絮。
@property(copy) CALayerContentsGravity contentsGravity;
屬性描述 :一個(gè)常量丛肢,指定CALayer(圖層)對(duì)象的內(nèi)容在其邊界內(nèi)的定位或縮放方式,此屬性的默認(rèn)值為kCAGravityResize剿干。
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(100, 150, 200, 200);
layer.contents = (id)[UIImage imageNamed:@"PokemonV"].CGImage;
layer.contentsGravity = kCAGravityResize;
[self.view.layer addSublayer:layer];
@property CGRect contentsRect;
屬性描述 :定義了將要繪制到圖層中的contents屬性的子矩形蜂怎,默認(rèn)為單位矩形(0.0, 0.0, 1.0, 1.0),可以動(dòng)畫置尔。如果請(qǐng)求單元矩形外的像素杠步,則contents圖像的邊緣像素將向外擴(kuò)展。如果提供了一個(gè)空矩形榜轿,則結(jié)果是未定義的幽歼。
例如 : layer.contentsRect = CGRectMake(0.0, 0.0, 0.5, 0.5)時(shí):
layer.contentsRect = CGRectMake(0.0, 0.0, 1.5, 1.5)時(shí):
@property CGFloat cornerRadius;
屬性描述 : 繪制CALayer對(duì)象背景圓角時(shí)使用的半徑,可設(shè)置動(dòng)畫谬盐。將半徑設(shè)置為大于0.0的值會(huì)導(dǎo)致圖層開始在其背景上繪制圓角甸私,默認(rèn)情況下,角半徑不應(yīng)用于層的contents屬性中的圖像设褐,它只適用于圖層的背景顏色和邊框颠蕴,但是如果將masksToBounds屬性設(shè)置為YES泣刹,會(huì)導(dǎo)致contents屬性中的圖像剪切到圓角助析。
@property CGFloat borderWidth;
屬性描述 :CALayer對(duì)象邊框的寬,可以做成動(dòng)畫椅您。當(dāng)該值大于0.0時(shí)外冀,根據(jù)此屬性中指定的值在調(diào)用方邊界插入屬性中指定的值來繪制邊框,使用當(dāng)前的borderColor值設(shè)置顏色掀泳,并最終在調(diào)用方的內(nèi)容和子層之上合成雪隧,并包括cornerRadius特性的影響西轩。此屬性的默認(rèn)值為0.0。
@property(nullable) CGColorRef borderColor;
屬性描述 : CALayer對(duì)象邊框的顏色脑沿,可以做成動(dòng)畫藕畔,此屬性的默認(rèn)值是不透明的黑色犁罩。
@property float shadowOpacity;
屬性描述 :CALayer對(duì)象陰影的不透明度坚踩,可以做成動(dòng)畫,此屬性中的值必須在0.0(透明)到1.0(不透明)的范圍內(nèi)澎埠,這個(gè)屬性的默認(rèn)值是0.0措近。
@property(nullable) CGColorRef shadowColor;
屬性描述 :CALayer對(duì)象陰影的顏色溶弟,可以做成動(dòng)畫,此屬性的默認(rèn)值是不透明的黑色瞭郑。
@property CGSize shadowOffset;
屬性描述 :CALayer對(duì)象陰影陰影的偏移(以點(diǎn)為單位)辜御,這個(gè)屬性的默認(rèn)值是(0.0,-3.0)屈张,寬度為負(fù)時(shí)陰影左移擒权,寬度為正時(shí)陰影右移,高度為負(fù)時(shí)陰影上移阁谆,高度為正時(shí)陰影下移菜拓,可以做成動(dòng)畫。
@property CGFloat shadowRadius;
屬性描述 :用于渲染CALayer對(duì)象陰影的模糊半徑(以點(diǎn)為單位)笛厦,這個(gè)屬性的默認(rèn)值是3.0纳鼎,可以做成動(dòng)畫。
@property(nullable) CGPathRef shadowPath;
屬性描述 :CALayer(圖層)對(duì)象陰影的形狀裳凸,該屬性的默認(rèn)值為nil贱鄙,這將導(dǎo)致該CALayer(圖層)對(duì)象使用標(biāo)準(zhǔn)的陰影形狀。如果為這個(gè)屬性指定了一個(gè)值姨谷,圖層會(huì)使用指定的路徑來創(chuàng)建它的陰影輪廓逗宁,并使用非零纏繞規(guī)則(圖形學(xué)中判斷一個(gè)點(diǎn)是否在自相交的多邊形內(nèi)部或外部的規(guī)則)結(jié)合當(dāng)前陰影顏色、不透明度和模糊半徑填充創(chuàng)建的陰影形狀梦湘。與大多數(shù)可動(dòng)畫屬性不同瞎颗,這個(gè)屬性(與所有CGPathRef可動(dòng)畫屬性一樣)不支持隱式動(dòng)畫,但是路徑對(duì)象可以使用CAPropertyAnimation的任何具體子類進(jìn)行動(dòng)畫捌议。
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(100, 150, 200, 200);
layer.contents = (id)[UIImage imageNamed:@"PokemonV"].CGImage;
layer.contentsGravity = kCAGravityResize;
layer.cornerRadius = 10.0;
layer.shadowOpacity = 0.5f;
layer.shadowOffset = CGSizeMake(-50, -50);
layer.shadowColor = [UIColor redColor].CGColor;
layer.shadowRadius = 10.0f;
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 300, 300)];
layer.shadowPath = path.CGPath;
[self.view.layer addSublayer:layer];
@property(nullable) CGColorRef backgroundColor;
屬性描述 :CALayer對(duì)象的背景顏色哼拔,此屬性的默認(rèn)值為nil,可以做成動(dòng)畫瓣颅。
@property CGFloat rasterizationScale;
屬性描述 :相對(duì)于圖層的坐標(biāo)空間倦逐,光柵化內(nèi)容的比例」梗可設(shè)置動(dòng)畫
@property BOOL shouldRasterize;
屬性描述 : 光柵化檬姥,指示layer在合成之前是否被渲染為位圖的布爾值曾我,可動(dòng)畫。啟用shouldRasterize屬性會(huì)將圖層繪制到一個(gè)屏幕之外的圖像健民,然后這個(gè)圖像將會(huì)被緩存起來抒巢。
如果有很多的子圖層或者有復(fù)雜的效果應(yīng)用,開啟shouldRasterize就會(huì)比重繪所有事務(wù)的所有幀劃得來得多秉犹。但是光柵化原始圖像需要時(shí)間虐秦,而且還會(huì)消耗額外的內(nèi)存。所以需要根據(jù)實(shí)際情況取舍凤优。單次使用或者視圖有變動(dòng)悦陋,shouldRasterize不會(huì)有任何用途,反而會(huì)犧牲內(nèi)存筑辨。對(duì)一個(gè)層級(jí)復(fù)雜的視圖做動(dòng)畫時(shí)俺驶,可以啟用shouldRasterize避免GPU每幀都重新合成。
調(diào)試方法:
xcode開發(fā)工具提供的常用的測(cè)量方式:
Xcode->Debug->View Debuging->Rendering->Color Offscrenn-rended Yellow可以為觸發(fā)了離屏渲染的layer著黃色棍辕。
Xcode->Debug->View Debuging->Rendering->Hits Green and Misses Red
這個(gè)指標(biāo)可以反映我們通過嘗試開啟shouldRasterize提升性能的時(shí)候是不是達(dá)到了預(yù)期效果暮现。
當(dāng)使用shouldRasterize屬性的時(shí)候,耗時(shí)的圖層繪制會(huì)被緩存楚昭,然后當(dāng)做一個(gè)簡(jiǎn)單的扁平圖片呈現(xiàn)栖袋。當(dāng)緩存再生的時(shí)候這個(gè)選項(xiàng)就用紅色對(duì)柵格化圖層進(jìn)行了高亮,緩存被重復(fù)使用的話就會(huì)以綠色進(jìn)行高亮抚太。如果緩存頻繁再生的話(紅色太多)塘幅,就意味著柵格化可能會(huì)有負(fù)面的性能影響了。
CALayer的常用函數(shù)
- (void)addSublayer:(CALayer *)layer;
函數(shù)描述 :將參數(shù)給定的CALayer對(duì)象添加到調(diào)用方的子層(sublayers)列表中尿贫。如果sublayers屬性中的數(shù)組為nil电媳,調(diào)用此方法將為sublayers屬性創(chuàng)建一個(gè)數(shù)組,并將指定的圖層添加到該屬性中庆亡。
參數(shù) :
layer : 要添加的CALayer對(duì)象匾乓。
- (void)insertSublayer:(CALayer *)layer atIndex:(unsigned)idx;
函數(shù)描述 :將參數(shù)給定的CALayer對(duì)象插入到調(diào)用方的子層列表中指定索引處的位置。
參數(shù) :
layer : 要插入到當(dāng)前調(diào)用方圖層層次結(jié)構(gòu)中的子圖層對(duì)象又谋。
idx : 插入圖層的索引拼缝,該值必須是子層數(shù)組中有效的索引。
- (void)insertSublayer:(CALayer *)layer below:(nullable CALayer *)sibling;
函數(shù)描述 :將參數(shù)給定的CALayer對(duì)象插入到調(diào)用方子層列表中指定的圖層之下彰亥。
參數(shù) :
layer :要插入到當(dāng)前調(diào)用方圖層層次結(jié)構(gòu)中的子圖層對(duì)象咧七。
sibling : 調(diào)用方指定的圖層。如果指定的圖層不在調(diào)用方的子層數(shù)組中剩愧,此方法將引發(fā)異常猪叙。
- (void)insertSublayer:(CALayer *)layer above:(nullable CALayer *)sibling;
函數(shù)描述 :將參數(shù)給定的CALayer對(duì)象插入到調(diào)用方子層列表中指定的圖層之上娇斩。
參數(shù) :
layer :要插入到當(dāng)前調(diào)用方圖層層次結(jié)構(gòu)中的子圖層對(duì)象仁卷。
sibling : 調(diào)用方指定的圖層穴翩。如果指定的圖層不在調(diào)用方的子層數(shù)組中,此方法將引發(fā)異常锦积。
- (void)replaceSublayer:(CALayer *)oldLayer with:(CALayer *)newLayer;
函數(shù)描述 :使用新的CALayer對(duì)象替換調(diào)用方指定的子圖層芒帕。
參數(shù) :
oldLayer : 調(diào)用方要被替換的子圖層。
newLayer : 用來替換oldLayer的圖層對(duì)象丰介。
- (void)removeFromSuperlayer;
函數(shù)描述 :將CALayer對(duì)象在其父級(jí)層(superlayer)移除背蟆。可以使用此方法從圖層的層次結(jié)構(gòu)中刪除一個(gè)層(及其所有子層)哮幢。此方法更新父級(jí)層(superlayer)的子層列表(sublayers)带膀,并將該CALayer對(duì)象的父級(jí)層(superlayer)屬性設(shè)置為nil。
CALayer關(guān)于動(dòng)畫的常用函數(shù)
- (void)addAnimation:(CAAnimation *)anim forKey:(nullable NSString *)key;
函數(shù)描述 :在調(diào)用函數(shù)的CALayer對(duì)象上附加一個(gè)動(dòng)畫對(duì)象橙垢。通常這是通過CAAnimation對(duì)象的操作隱式調(diào)用的垛叨。
“key”可以是任何字符串,這樣每個(gè)唯一的key在每個(gè)CALayer對(duì)象上只添加一個(gè)動(dòng)畫柜某。特殊的key值“transition”是自動(dòng)用于過渡動(dòng)畫嗽元,并且nil指針也是一個(gè)有效的鍵。
如果動(dòng)畫的“duration”屬性為0或負(fù)值喂击,則會(huì)給它默認(rèn)的持續(xù)時(shí)間剂癌,否則為“animationDuration”事務(wù)屬性的值或0.25秒。
動(dòng)畫在被添加到圖層之前會(huì)被復(fù)制翰绊,所以任何對(duì)“anim”的后續(xù)修改都不會(huì)有影響佩谷,除非它被添加到另一個(gè)圖層。
參數(shù) :
anim : 要添加到渲染樹的動(dòng)畫监嗜。此對(duì)象由渲染樹復(fù)制琳要,而不是引用。因此秤茅,對(duì)對(duì)象的后續(xù)修改不會(huì)傳播到渲染樹中稚补。
key : 標(biāo)識(shí)動(dòng)畫的字符串,每一個(gè)唯一的key只有一個(gè)動(dòng)畫被添加到調(diào)用該函數(shù)的圖層框喳。特殊的key值“kCATransition”自動(dòng)用于過渡動(dòng)畫课幕,也可以為該參數(shù)指定nil。
- (void)removeAllAnimations;
函數(shù)描述 :調(diào)用該函數(shù)的CALayer對(duì)象上所附加的全部動(dòng)畫都將被刪除五垮。
- (void)removeAnimationForKey:(NSString *)key;
函數(shù)描述 : 在調(diào)用該函數(shù)的CALayer對(duì)象上移除使用指定的key標(biāo)識(shí)的動(dòng)畫對(duì)象乍惊。
參數(shù) :
key : 要移除的動(dòng)畫的標(biāo)識(shí)符。
CAGradientLayer - 顏色漸變層
CAGradientLayer繼承CALayer放仗,是可以在其背景色上繪制顏色漸變的圖層润绎,默認(rèn)情況下顏色均勻地分布在整個(gè)圖層中,但可以通過選擇指定的漸變位置來控制顏色的位置。
CAGradientLayer常用屬性
@property CGPoint startPoint;
函數(shù)描述:在圖層的坐標(biāo)空間中繪制漸變時(shí)的起點(diǎn)莉撇,可設(shè)置動(dòng)畫呢蛤。起點(diǎn)對(duì)應(yīng)于梯度的第一個(gè)停止點(diǎn),該點(diǎn)在單位坐標(biāo)空間中定義棍郎,然后在繪制時(shí)映射到層的邊界矩形其障。默認(rèn)值為(0.5,0.0)。
@property CGPoint endPoint;
函數(shù)描述:在圖層的坐標(biāo)空間中繪制漸變時(shí)的終點(diǎn)涂佃,可設(shè)置動(dòng)畫励翼。終點(diǎn)對(duì)應(yīng)于漸變的最后一個(gè)停止點(diǎn),該點(diǎn)在單位坐標(biāo)空間中定義辜荠,然后在繪制時(shí)映射到層的邊界矩形汽抚。默認(rèn)值為(0.5,1.0)。
@property(nullable, copy) NSArray *colors;
函數(shù)描述:CGColorRef對(duì)象的數(shù)組伯病,定義每個(gè)漸變停止點(diǎn)的顏色殊橙。數(shù)組中只設(shè)置一個(gè)顏色是不顯示的∮樱可設(shè)置動(dòng)畫膨蛮。
@property(copy) CAGradientLayerType type;
函數(shù)描述:圖層繪制漸變時(shí)的樣式。默認(rèn)值為kCAGradientLayerAxial季研。
- CAGradientLayerType列舉的樣式:
// 軸向梯度(也稱為線性梯度)沿兩個(gè)定義端點(diǎn)之間的軸變化敞葛,垂直于這條軸線上的線條中所有點(diǎn)都具有相同的顏色值。
CA_EXTERN CAGradientLayerType const kCAGradientLayerAxial
API_AVAILABLE(macos(10.6), ios(3.0), watchos(2.0), tvos(9.0));
//徑向梯度与涡。漸變被定義為一個(gè)橢圓惹谐,它的中心是` startPoint `,寬度和高度定義為` (endPoint.x - startPoint.x) * 2 ` 和 `(endPoint.y - startPoint.y) * 2'驼卖。
//徑向梯度是沿兩個(gè)限定端之間的軸徑向變化的填充,其通常都是圓
CA_EXTERN CAGradientLayerType const kCAGradientLayerRadial
API_AVAILABLE(macos(10.6), ios(3.2), watchos(2.0), tvos(9.0));
//錐形漸變氨肌。梯度以“startPoint”為中心,其0度方向由“startPoint”和“endPoint”之間的矢量定義酌畜。
//當(dāng)“startPoint”和“endPoint”重疊時(shí)怎囚,結(jié)果未定義。梯度的角度在正x軸朝向正y軸的旋轉(zhuǎn)方向上增加桥胞。
CA_EXTERN CAGradientLayerType const kCAGradientLayerConic
API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
- (void)setGradualChangeColorView:(UIView *)view{
//CAGradientLayer繼承CALayer恳守,可以設(shè)置漸變圖層
CAGradientLayer *grandientLayer = [[CAGradientLayer alloc] init];
grandientLayer.frame = view.bounds;
[view.layer addSublayer:grandientLayer];
[view.layer insertSublayer:grandientLayer atIndex:0];
//設(shè)置漸變的方向 左上(0,0) 右下(1,1)
grandientLayer.startPoint = CGPointZero;
grandientLayer.endPoint = CGPointMake(0.0, 1.0);
//colors漸變的顏色數(shù)組 這個(gè)數(shù)組中只設(shè)置一個(gè)顏色是不顯示的
grandientLayer.colors = @[(id)[UIColor redColor].CGColor, (id)[UIColor greenColor].CGColor];
grandientLayer.type = kCAGradientLayerAxial;
}
- (void)viewDidLoad {
[super viewDidLoad];
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 50, CGRectGetMidY(self.view.frame) - 50, 100, 100)];
[self.view addSubview:view];
[self setGradualChangeColorView:view];
}
CAReplicatorLayer -- 復(fù)制層
CAReplicatorLayer繼承自CALayer,是一個(gè)Layer容器贩虾,添加到容器上的子Layer可以復(fù)制若干份催烘,可以設(shè)定子Layer復(fù)制份數(shù)、設(shè)定副本之間的距離缎罢、透明度伊群、顏色考杉、旋轉(zhuǎn)、位置等舰始,可以使用CAReplicatorLayer對(duì)象來基于單一源層構(gòu)建復(fù)雜的布局崇棠。
CAReplicatorLayer的屬性
@property CFTimeInterval instanceDelay;
屬性描述 :指定復(fù)制每個(gè)圖層副本之間的延遲(以秒為單位),可設(shè)置動(dòng)畫蔽午,默認(rèn)值為0.0易茬,這意味著添加到被復(fù)制出的圖層副本上的任何動(dòng)畫都將同步酬蹋。
@property NSInteger instanceCount;
屬性描述 :要通過復(fù)制創(chuàng)建的圖層副本數(shù)量及老,其中包括源圖層,默認(rèn)值為1范抓,不創(chuàng)建額外圖層副本骄恶。
@property CATransform3D instanceTransform;
屬性描述 :通過對(duì)前一實(shí)例的矩陣轉(zhuǎn)換來生成當(dāng)前實(shí)例,可以做成動(dòng)畫匕垫,轉(zhuǎn)換的矩陣相對(duì)于該圖層中心的位置應(yīng)用僧鲁,默認(rèn)是單位矩陣。
@property BOOL preservesDepth;
屬性描述 :定義此層是否將其子層展平到其平面中象泵。如果YES寞秃,則該層的行為與CATTransfermLayer相似,并且具有相同的限制偶惠,默認(rèn)值為NO春寿。
@property(nullable) CGColorRef instanceColor;
屬性描述 :定義源圖層對(duì)象的顏色,可以做成動(dòng)畫忽孽,默認(rèn)為不透明白色绑改。
@property float instanceRedOffset;
屬性描述 :定義添加到每個(gè)復(fù)制實(shí)例的顏色的紅色分量的偏移量,可設(shè)置動(dòng)畫兄一,通過對(duì)前一實(shí)例顏色的紅色分量添加instanceRedOffset以生成當(dāng)前實(shí)例的調(diào)制顏色厘线。
@property float instanceGreenOffset;
屬性描述 :定義添加到每個(gè)復(fù)制實(shí)例的顏色的綠色分量的偏移量,可設(shè)置動(dòng)畫出革,通過對(duì)前一實(shí)例顏色的綠色分量添加instanceGreenOffset以生成當(dāng)前實(shí)例的調(diào)制顏色造壮。
@property float instanceBlueOffset;
屬性描述 :定義添加到每個(gè)復(fù)制實(shí)例的顏色的藍(lán)色分量的偏移量,可設(shè)置動(dòng)畫骂束,通過對(duì)前一實(shí)例顏色的藍(lán)色分量添加instanceBlueOffset以生成當(dāng)前實(shí)例的調(diào)制顏色费薄。
@property float instanceAlphaOffset;
屬性描述 :定義添加到每個(gè)復(fù)制實(shí)例的顏色的透明度分量的偏移量,可設(shè)置動(dòng)畫栖雾,通過對(duì)前一實(shí)例顏色的透明度分量添加instanceAlphaOffset以生成當(dāng)前實(shí)例的調(diào)制顏色楞抡。
創(chuàng)建一個(gè)網(wǎng)格,第一行五個(gè)正方形顏色從白色漸變?yōu)榧t色析藕,垂直方向上每個(gè)正方形紅色偏移量值逐漸減小 :
- (void)viewDidLoad {
[super viewDidLoad];
//初始化紅色方塊層對(duì)象
CALayer *redSquare = [CALayer layer];
redSquare.backgroundColor = [UIColor whiteColor].CGColor;
redSquare.borderWidth = 1.0;
redSquare.borderColor = [UIColor greenColor].CGColor;
redSquare.frame = CGRectMake(0, 0, 25, 25);
//初始化復(fù)制層對(duì)象
CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer];
//通過復(fù)制創(chuàng)建的圖層副本數(shù)
NSInteger instanceCount = 5;
replicatorLayer.instanceCount = instanceCount;
//通過對(duì)前一實(shí)例的矩陣轉(zhuǎn)換來生成當(dāng)前實(shí)例
replicatorLayer.instanceTransform = CATransform3DMakeTranslation(50, 0, 0);
//設(shè)置顏色分量偏移量
CGFloat offsetStep = -1.0 / instanceCount;
replicatorLayer.instanceBlueOffset = offsetStep;
replicatorLayer.instanceGreenOffset = offsetStep;
//添加紅色方塊層對(duì)象到復(fù)制層
[replicatorLayer addSublayer:redSquare];
//初始化外層復(fù)制層對(duì)象
CAReplicatorLayer *outerReplicatorLayer = [CAReplicatorLayer layer];
//嵌套復(fù)制層
[outerReplicatorLayer addSublayer:replicatorLayer];
//通過復(fù)制創(chuàng)建的圖層副本數(shù)
outerReplicatorLayer.instanceCount = instanceCount;
//通過對(duì)前一實(shí)例的矩陣轉(zhuǎn)換來生成當(dāng)前實(shí)例
outerReplicatorLayer.instanceTransform = CATransform3DMakeTranslation(0, 110, 0);
//設(shè)置顏色分量偏移量
outerReplicatorLayer.instanceRedOffset = offsetStep;
//顯示外層復(fù)制層對(duì)象
outerReplicatorLayer.position = CGPointMake(0, 200);
[self.view.layer addSublayer:outerReplicatorLayer];
}
- (void)viewDidLoad {
[super viewDidLoad];
//初始化圓點(diǎn)圖層
CALayer *circle = [CALayer layer];
circle.frame = CGRectMake(0, 0, 10, 10);
circle.backgroundColor = UIColor.blueColor.CGColor;
circle.cornerRadius = 5;
circle.position = CGPointMake(0, 50);
//圓點(diǎn)圖層上的透明度動(dòng)畫
CABasicAnimation *fadeOut = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeOut.fromValue = @(1);
fadeOut.toValue = @(0);
fadeOut.duration = 1;
fadeOut.repeatCount = CGFLOAT_MAX;
[circle addAnimation:fadeOut forKey:nil];
//復(fù)制層
CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer];
//添加圓點(diǎn)圖層到復(fù)制層
[replicatorLayer addSublayer:circle];
//通過復(fù)制創(chuàng)建的圖層副本數(shù)
NSNumber *instanceCount = @(30);
replicatorLayer.instanceCount = instanceCount.integerValue;
//指定復(fù)制每個(gè)圖層副本之間的延遲
replicatorLayer.instanceDelay = fadeOut.duration / instanceCount.doubleValue;
//過對(duì)前一實(shí)例的矩陣轉(zhuǎn)換來生成當(dāng)前實(shí)例
CGFloat angle = -M_PI * 2 / instanceCount.floatValue;
replicatorLayer.instanceTransform = CATransform3DMakeRotation(angle, 0, 0, 1);
//顯示復(fù)制層對(duì)象
replicatorLayer.frame = CGRectMake(CGRectGetMidX(self.view.frame) - 50, CGRectGetMidY(self.view.frame) - 50, 100, 100);
[self.view.layer addSublayer:replicatorLayer];
}
@interface TestCodeController ()
@end
@implementation TestCodeController
- (void)viewDidLoad {
[super viewDidLoad];
UIView *aniView = [[UIView alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width / 2 - 40, CGRectGetMidY(self.view.frame) , 5, 20)];
[self.view addSubview:aniView];
[aniView.layer addSublayer: [self replicatorLayer_Shake]];
}
// 震動(dòng)條動(dòng)畫
- (CALayer *)replicatorLayer_Shake{
//初始化層對(duì)象
CALayer *layer = [[CALayer alloc]init];
//層對(duì)象框架矩形
layer.frame = CGRectMake(0, 0, 10, 32);
//設(shè)置圓角
layer.cornerRadius = 5.0f;
//設(shè)置層背景色
layer.backgroundColor = [UIColor redColor].CGColor;
//定義層邊界矩形的定位點(diǎn)召廷,可設(shè)置動(dòng)畫
layer.anchorPoint = CGPointMake(0.5, 0.5);
// 添加一個(gè)對(duì)Y方向進(jìn)行縮放的基本動(dòng)畫
[layer addAnimation:[self scaleYAnimation] forKey:@"scaleAnimation"];
//初始化復(fù)制層
CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer];
//復(fù)制層框架矩形
replicatorLayer.frame = CGRectMake(0, 0, 80, 80);
//要?jiǎng)?chuàng)建的副本數(shù)
replicatorLayer.instanceCount = 3;
//復(fù)制矩陣
replicatorLayer.instanceTransform = CATransform3DMakeTranslation(20, 0, 0);
//指定復(fù)制副本之間的延遲(秒)
replicatorLayer.instanceDelay = 0.2;
//為每個(gè)復(fù)制的實(shí)例定義添加到組件的顏色的綠色偏移量,可設(shè)置動(dòng)畫
replicatorLayer.instanceGreenOffset = 10;
//將層對(duì)象添加到復(fù)制層容器
[replicatorLayer addSublayer:layer];
//返回復(fù)制層容器
return replicatorLayer;
}
//對(duì)Y方向進(jìn)行縮放的基本動(dòng)畫
- (CABasicAnimation *)scaleYAnimation{
//對(duì)Y方向進(jìn)行縮放的基本動(dòng)畫
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.scale.y"];
//縮放結(jié)束值
anim.toValue = @0.1;
//動(dòng)畫持續(xù)時(shí)間
anim.duration = 0.4;
//動(dòng)畫完成后是否在層中移除
anim.removedOnCompletion = NO;
//動(dòng)畫結(jié)束是否執(zhí)行逆動(dòng)畫
anim.autoreverses = YES;
//動(dòng)畫重復(fù)次數(shù)為無(wú)限重復(fù)
anim.repeatCount = MAXFLOAT;
//返回/對(duì)Y方向進(jìn)行縮放的基本動(dòng)畫
return anim;
}
@end
效果如圖:
CAAnimation - 動(dòng)畫的抽象超類
CAAnimation蔬芥,核心動(dòng)畫中動(dòng)畫的抽象超類常遂。繼承自NSObject掰吕,遵循了NSSecureCoding银亲、 NSCopying,先煎、CAMediaTiming,助泽、CAAction協(xié)議楞慈,CAAnimation為CAMediaTiming和CAAction協(xié)議提供了基本的支持旺嬉。不要?jiǎng)?chuàng)建CAAnimation實(shí)例:要使核心動(dòng)畫層或SceneKit對(duì)象具有動(dòng)畫效果败潦,請(qǐng)創(chuàng)建具體子類CABasicAnimation本冲、CAKeyframeAnimation、CAAnimationGroup或CATransition的實(shí)例劫扒。
CAAnimation提供的屬性
@property(nullable, strong) CAMediaTimingFunction *timingFunction;
屬性描述 :一個(gè)可選的計(jì)時(shí)函數(shù)檬洞,用來定義動(dòng)畫的節(jié)奏。默認(rèn)為nil沟饥,表示線性節(jié)奏添怔。
@property(nullable, strong) id <CAAnimationDelegate> delegate;
屬性描述 :指定調(diào)用方的代理對(duì)象,代理對(duì)象由調(diào)用方保留贤旷。CAAnimation的實(shí)例不應(yīng)該被設(shè)置為它自己的代理广料,這樣做將導(dǎo)致保留周期。
@property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;
屬性描述:確定動(dòng)畫是否在完成時(shí)從目標(biāo)圖層的動(dòng)畫中移除幼驶。如果為“YES”艾杏,動(dòng)畫將在其活動(dòng)持續(xù)時(shí)間過后從目標(biāo)圖層的動(dòng)畫中移除。默認(rèn)為“YES”县遣。
CAAnimation提供的函數(shù)
+ (instancetype)animation;
函數(shù)描述 : 創(chuàng)建并返回一個(gè)新的CAAnimation實(shí)例糜颠。
+ (nullable id)defaultValueForKey:(NSString *)key;
屬性描述 : 使用指定鍵指定調(diào)用方屬性的默認(rèn)值。如果此方法返回nil萧求,則根據(jù)鍵的聲明類型為屬性提供一個(gè)合適的“zero”默認(rèn)值其兴。例如,如果key是CGSize對(duì)象夸政,則返回大小為(0.0,0.0)的值元旬;對(duì)于CGRect,返回一個(gè)空矩形守问;對(duì)于CGAffineTransform和CATransform3D匀归,返回適當(dāng)?shù)膯挝痪仃嚒?/p>
參數(shù) :
key :調(diào)用方屬性之一的名稱。
返回值 :
指定屬性的默認(rèn)值耗帕,如果沒有設(shè)置默認(rèn)值穆端,則返回nil。
- (BOOL)shouldArchiveValueForKey:(NSString *)key;
屬性描述 :指定是否要?dú)w檔給定鍵的屬性值仿便。由對(duì)象的實(shí)現(xiàn)encodeWithCoder:調(diào)用体啰,對(duì)象必須實(shí)現(xiàn)鍵歸檔攒巍,默認(rèn)實(shí)現(xiàn)返回YES。
參數(shù) :
key : 調(diào)用方屬性之一的名稱荒勇。
返回值 :
如果要?dú)w檔指定的屬性柒莉,則為“YES”,否則為“NO”沽翔。
CAAnimation提供的代理函數(shù)
- (void)animationDidStart:(CAAnimation *)anim;
函數(shù)描述 : 通知代理動(dòng)畫已開始兢孝。
參數(shù) :
anim : 已啟動(dòng)的CAAnimation對(duì)象。
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
函數(shù)描述 :通知代理動(dòng)畫已結(jié)束仅偎。動(dòng)畫結(jié)束的原因可能是已達(dá)到動(dòng)畫活動(dòng)持續(xù)時(shí)間跨蟹,或者動(dòng)畫在其附著的圖層中被移除,如果動(dòng)畫因?yàn)檫_(dá)到其活動(dòng)持續(xù)時(shí)間后而結(jié)束哨颂,flag為YES喷市。
參數(shù) :
anim :結(jié)束的動(dòng)畫對(duì)象相种。
flag : 指示動(dòng)畫是否因?yàn)檫_(dá)到其活動(dòng)持續(xù)時(shí)間后而結(jié)束的標(biāo)志威恼。
CAMediaTiming協(xié)議
CAMediaTiming協(xié)議建模了一個(gè)分層計(jì)時(shí)系統(tǒng),CALayer與CAAnimation 都實(shí)現(xiàn)了該協(xié)議寝并,協(xié)議中定義了在一段動(dòng)畫內(nèi)用來控制時(shí)間的屬性的集合箫措。
@property CFTimeInterval duration;
屬性描述 :指定動(dòng)畫每執(zhí)行一次的基本持續(xù)時(shí)間(秒),默認(rèn)為值為0衬潦,但仍舊有0.25秒的動(dòng)畫斤蔓。
@property float speed;
屬性描述 :相對(duì)于duration所設(shè)置時(shí)間的流逝倍速,值越大則duration所設(shè)置的流逝時(shí)間越快镀岛。例如duration設(shè)置動(dòng)畫持續(xù)時(shí)間為10秒弦牡,speed設(shè)置為2.0,則5秒即完成動(dòng)畫漂羊。
@property CFTimeInterval timeOffset;
屬性描述 :時(shí)間偏移驾锰,動(dòng)畫會(huì)在設(shè)置的偏移秒數(shù)開始執(zhí)行,并執(zhí)行duration所設(shè)置的持續(xù)時(shí)間走越。例如duration設(shè)置動(dòng)畫持續(xù)時(shí)間為10秒椭豫,timeOffset設(shè)置為5.0,則動(dòng)畫在5秒處開始旨指,并運(yùn)行10秒赏酥。
@property float repeatCount;
屬性描述 :動(dòng)畫的重復(fù)次數(shù),如果repeatCount為0谆构,則忽略該屬性裸扶,默認(rèn)為0,將此屬性設(shè)置為HUGE_VALF將導(dǎo)致動(dòng)畫永遠(yuǎn)重復(fù)搬素。如果同時(shí)指定了repeatDuration和repeatCount呵晨,則行為未定義瞬项。
@property CFTimeInterval repeatDuration;
屬性描述 :動(dòng)畫將重復(fù)執(zhí)行的時(shí)間(秒),如果小于duration所設(shè)置時(shí)間何荚,則動(dòng)畫只執(zhí)行repeatDuration所設(shè)置時(shí)間(秒)的部分囱淋,如果大于duration所設(shè)置時(shí)間,動(dòng)畫將重復(fù)執(zhí)行repeatDuration超出duration所設(shè)置時(shí)間的部分餐塘。該屬性不受speed屬性的影響妥衣,且與repeatDuration屬性沖突。為0則忽略該屬性戒傻,默認(rèn)為0税手。
@property BOOL autoreverses;
屬性描述 :動(dòng)畫在執(zhí)行一次后是否執(zhí)行逆動(dòng)畫,如果為YES需纳,動(dòng)畫在正向執(zhí)行一次后芦倒,反向執(zhí)行一次。默認(rèn)為NO不翩。
@property(copy) CAMediaTimingFillMode fillMode;
屬性描述 :指定動(dòng)畫開始之前與結(jié)束之后對(duì)動(dòng)畫時(shí)間上的一種填充兵扬,默認(rèn)值為kCAFillModeRemoved,可選值如下:
//當(dāng)動(dòng)畫完成時(shí)口蝠,以最終的可見狀態(tài)作為填充
CA_EXTERN CAMediaTimingFillMode const kCAFillModeForwards
API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
//動(dòng)畫開始之前器钟,以動(dòng)畫的第一幀作為填充
CA_EXTERN CAMediaTimingFillMode const kCAFillModeBackwards
API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
//結(jié)合kCAFillModeForwards與kCAFillModeBackwards,即以最終的可見狀態(tài)填充動(dòng)畫完成時(shí)妙蔗,以動(dòng)畫的第一幀填充動(dòng)畫開始之前
CA_EXTERN CAMediaTimingFillMode const kCAFillModeBoth
API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
//動(dòng)畫完成后將移除傲霸,無(wú)填充
CA_EXTERN CAMediaTimingFillMode const kCAFillModeRemoved
API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
@property CFTimeInterval beginTime;
屬性描述 :如果適用,指定相對(duì)于其父對(duì)象的開始時(shí)間(延遲時(shí)間)眉反。例如在動(dòng)畫在CAAnimationGroup動(dòng)畫組中昙啄,那么動(dòng)畫的開始時(shí)間是相對(duì)于CAAnimationGroup動(dòng)畫組動(dòng)畫開始的延遲,如果直接添加在CALayer(圖層)中寸五,則需要獲取CALayer(圖層)被添加的時(shí)間后梳凛,根據(jù)CALayer(圖層)被添加的時(shí)間設(shè)置延遲。
CATransition - 轉(zhuǎn)場(chǎng)動(dòng)畫
CATransition繼承自CAAnimation播歼,在圖層狀態(tài)之間提供動(dòng)畫轉(zhuǎn)換的對(duì)象伶跷。通過創(chuàng)建并向?qū)又刑砑覥ATransition對(duì)象,可以在圖層的狀態(tài)之間進(jìn)行轉(zhuǎn)換秘狞,默認(rèn)過渡是交叉淡入叭莫,但可以指定與一組預(yù)定義過渡不同的效果。
CATransition提供的屬性
@property(copy) CATransitionType type;
屬性描述 :指定預(yù)定義的轉(zhuǎn)換類型烁试」统酰可能的值以常見的轉(zhuǎn)換類型顯示。如果在篩選器屬性中指定了自定義轉(zhuǎn)換减响,則忽略此屬性靖诗。默認(rèn)值為kCATransitionFade郭怪。
//當(dāng)圖層變得可見或隱藏時(shí),其內(nèi)容將逐漸消失刊橘。
CA_EXTERN CATransitionType const kCATransitionFade
//該層的內(nèi)容在任何現(xiàn)有內(nèi)容上滑動(dòng)到位鄙才。公共轉(zhuǎn)換子類型用于此轉(zhuǎn)換。
CA_EXTERN CATransitionType const kCATransitionMoveIn
//該層的內(nèi)容推動(dòng)任何現(xiàn)有內(nèi)容促绵,因?yàn)樗瑒?dòng)到位攒庵。公共轉(zhuǎn)換子類型用于此轉(zhuǎn)換。
CA_EXTERN CATransitionType const kCATransitionPush
//層的內(nèi)容按轉(zhuǎn)換子類型指定的方向逐漸顯示败晴。公共轉(zhuǎn)換子類型用于此轉(zhuǎn)換浓冒。
CA_EXTERN CATransitionType const kCATransitionReveal
@property(nullable, copy) CATransitionSubtype subtype;
屬性描述 :指定一個(gè)可選子類型,該子類型預(yù)定義了基于運(yùn)動(dòng)的變換方向尖坤∥壤粒可能的值顯示在公共轉(zhuǎn)換子類型中,默認(rèn)值為nil慢味。
//過渡從層的右側(cè)開始场梆。
CA_EXTERN CATransitionSubtype const kCATransitionFromRight
//過渡從層的左側(cè)開始。
CA_EXTERN CATransitionSubtype const kCATransitionFromLeft
//過渡從層的頂部開始贮缕。
CA_EXTERN CATransitionSubtype const kCATransitionFromTop
//過渡從層的底部開始辙谜。
CA_EXTERN CATransitionSubtype const kCATransitionFromBottom
@property float startProgress;
屬性描述 :指示調(diào)用方的起點(diǎn)俺榆,作為整個(gè)轉(zhuǎn)換的一部分感昼,合法值是介于0.0和1.0之間的數(shù)字。例如罐脊,要在轉(zhuǎn)換過程的一半開始定嗓,請(qǐng)將startProgress設(shè)置為0.5。默認(rèn)值為0萍桌。
@property float endProgress;
屬性描述 :指示調(diào)用方的終點(diǎn)宵溅,作為整個(gè)轉(zhuǎn)換的一部分,該值必須大于或等于startProgress上炎,且不大于1.0恃逻。如果endProgress小于startProgress,則行為未定義藕施。默認(rèn)值是1.0寇损。
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *transitionBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[transitionBtn setTitle:@"轉(zhuǎn)場(chǎng)動(dòng)畫" forState:UIControlStateNormal];
[transitionBtn setBackgroundColor:[UIColor blueColor]];
transitionBtn.titleLabel.font = [UIFont systemFontOfSize:15];
[transitionBtn addTarget:self action:@selector(transitionBtnClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:transitionBtn];
[transitionBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).offset(100);
make.centerX.equalTo(self.view);
make.size.mas_equalTo(CGSizeMake(75, 35));
}];
}
//轉(zhuǎn)場(chǎng)動(dòng)畫按鈕點(diǎn)擊
- (void)transitionBtnClick{
UIView *view = [[UIView alloc]initWithFrame:CGRectZero];
view.backgroundColor = [UIColor redColor];
CATransition *animation = [CATransition animation];
animation.delegate = self;
//動(dòng)畫持續(xù)時(shí)間
animation.duration = 0.4;
//減緩速度,這會(huì)導(dǎo)致動(dòng)畫快速開始裳食,然后隨著它的進(jìn)展而緩慢矛市。
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
//動(dòng)畫為推出類型
animation.type = kCATransitionPush;
//方向,向上方推出
animation.subtype = kCATransitionFromTop;
//添加動(dòng)畫
[view.layer addAnimation:animation forKey:@"animation1"];
//布局視圖
[self.view addSubview:view];
[view mas_remakeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(self.view.mas_bottom);
make.size.mas_equalTo(CGSizeMake(SCREEN_WIDTH, 360));
}];
}
簡(jiǎn)單的推出效果 :
CAAnimationGroup - 分組動(dòng)畫
CAAnimationGroup繼承自CAAnimation诲祸,允許多個(gè)動(dòng)畫被分組并同時(shí)運(yùn)行的對(duì)象浊吏。分組中添加的動(dòng)畫會(huì)在CAAnimationGroup實(shí)例指定的時(shí)間空間中運(yùn)行而昨,分組中添加的動(dòng)畫時(shí)間如果超過CAAnimationGroup實(shí)例設(shè)置的動(dòng)畫持續(xù)時(shí)間,則添加的動(dòng)畫被剪切到動(dòng)畫組的持續(xù)時(shí)間找田。例如歌憨,在動(dòng)畫組中添加的動(dòng)畫持續(xù)時(shí)間10秒,但CAAnimationGroup實(shí)例設(shè)置的持續(xù)時(shí)間為5秒墩衙,則只顯示動(dòng)畫的前5秒躺孝。
動(dòng)畫數(shù)組中添加的動(dòng)畫其設(shè)置的代理和removedOnCompletion屬性目前會(huì)被忽略。由CAAnimationGroup的代理接收這些消息底桂。
CAAnimationGroup提供的屬性
@property(nullable, copy) NSArray<CAAnimation *> *animations;
屬性描述 : 要在調(diào)用方的時(shí)間空間內(nèi)計(jì)算的一組CAAnimation對(duì)象植袍。動(dòng)畫同時(shí)在接收方的時(shí)間空間中運(yùn)行。
@property(nullable, copy) NSArray<CAAnimation *> *animations;
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor = [UIColor blueColor];
[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
button.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[button.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[button.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
]];
self.myView = [[MyView alloc]initWithFrame:CGRectZero];
self.myView.layer.contents = (id)[UIImage imageNamed:@"darts"].CGImage;
[self.view addSubview:self.myView];
self.myView.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[self.myView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.myView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
[self.myView.widthAnchor constraintEqualToConstant:100],
[self.myView.heightAnchor constraintEqualToConstant:100],
]];
}
- (void)buttonClick:(UIButton *)sender {
CABasicAnimation * rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
rotateAnimation.fromValue = [NSNumber numberWithFloat:0];
rotateAnimation.toValue = [NSNumber numberWithFloat:M_PI * 2 + M_LN2];
rotateAnimation.duration = 0.25f;
rotateAnimation.repeatCount = HUGE_VALF;
rotateAnimation.beginTime = 1.0f;
CAKeyframeAnimation* frameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position.x"];
frameAnimation.values = @[@50,@(UIScreen.mainScreen.bounds.size.width - 50)];
frameAnimation.keyTimes = @[@0,@1];
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[rotateAnimation,frameAnimation];
group.duration = 5.0f;
group.fillMode = kCAFillModeForwards;
group.removedOnCompletion = NO;
[self.myView.layer addAnimation:group forKey:nil];
}
旋轉(zhuǎn)加移動(dòng) :
CAPropertyAnimation - 屬性動(dòng)畫
繼承自CAAnimation籽懦,是CAAnimation的一個(gè)抽象子類于个,用于創(chuàng)建操作圖層屬性值的動(dòng)畫,通常不直接使用暮顺,而是使用其子類CABasicAnimation或CAKeyframeAnimation厅篓。
CAPropertyAnimation提供的屬性
@property(nullable, copy) NSString *keyPath;
屬性描述 :對(duì)某個(gè)屬性需要設(shè)置動(dòng)畫的字符串描述,例如使用這一字符串@"position.x"描述動(dòng)畫在CGPoint中心點(diǎn)X軸方向改變位置捶码。
@property(getter=isAdditive) BOOL additive;
屬性描述 : 在動(dòng)畫每次執(zhí)行后羽氮,是否將動(dòng)畫指定的值添加到當(dāng)前渲染樹中的值以生成新的渲染樹值,如果為YES惫恼,動(dòng)畫指定的值將會(huì)添加到屬性的當(dāng)前渲染樹值中档押,以生成新的渲染樹值。例如在keypath為@"position.x"描述的動(dòng)畫中祈纯,該屬性為YES時(shí)令宿,position.x += value,該屬性為NO時(shí)腕窥,position.x = value粒没。該屬性默認(rèn)為NO。(注:在動(dòng)畫設(shè)置重復(fù)執(zhí)行時(shí)簇爆,在重復(fù)的過程中癞松,該值為YES,值也不會(huì)在動(dòng)畫重復(fù)過程中累加)
例如在下面的代碼中入蛆,可以比較直觀的觀察additive屬性變化的不同效果:
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor = [UIColor blueColor];
[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
button.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[button.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[button.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
]];
self.myView = [[MyView alloc]initWithFrame:CGRectZero];
self.myView.layer.contents = (id)[UIImage imageNamed:@"darts"].CGImage;
[self.view addSubview:self.myView];
self.myView.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[self.myView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.myView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
[self.myView.widthAnchor constraintEqualToConstant:100],
[self.myView.heightAnchor constraintEqualToConstant:100],
]];
}
- (void)buttonClick:(UIButton *)sender {
CABasicAnimation * rotateAnimation = [CABasicAnimation animationWithKeyPath:@"position.x"];
rotateAnimation.fromValue = @(50);
rotateAnimation.toValue = @(100);
rotateAnimation.duration = 1.0f;
rotateAnimation.repeatCount = 1;
rotateAnimation.fillMode = kCAFillModeForwards;
rotateAnimation.removedOnCompletion = NO;
rotateAnimation.additive = YES;
[self.myView.layer addAnimation:rotateAnimation forKey:nil];
}
當(dāng)additive為YES時(shí)响蓉,點(diǎn)擊執(zhí)行三次動(dòng)畫:
當(dāng)additive為NO時(shí),點(diǎn)擊執(zhí)行三次動(dòng)畫:
@property(getter=isCumulative) BOOL cumulative;
屬性描述 : cumulative屬性影響重復(fù)動(dòng)畫生成結(jié)果的方式安寺。如果為YES厕妖,則動(dòng)畫的當(dāng)前值是上一個(gè)重復(fù)周期結(jié)束時(shí)的值,加上當(dāng)前重復(fù)周期的值挑庶。如果為NO言秸,則該值只是為當(dāng)前重復(fù)周期計(jì)算的值软能。默認(rèn)為NO。與additive效果類似举畸,不過該屬性是作用在動(dòng)畫重復(fù)過程中的查排。
@property(nullable, strong) CAValueFunction *valueFunction;
屬性描述 : 如果為非nil值,則定義了為目標(biāo)屬性插入新值的動(dòng)畫方式的函數(shù)抄沮,默認(rèn)為nil跋核。valueFunction是專門為了transform動(dòng)畫而設(shè)置的,包括旋轉(zhuǎn)叛买、縮放砂代、平移等。
- (void)buttonClick:(UIButton *)sender {
CABasicAnimation * rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
rotateAnimation.fromValue = [NSNumber numberWithFloat:0];
rotateAnimation.toValue = [NSNumber numberWithFloat:100];
rotateAnimation.duration = 1.0f;
rotateAnimation.repeatCount = HUGE_VALF;
rotateAnimation.valueFunction = [CAValueFunction functionWithName:kCAValueFunctionTranslateX];
[self.myView.layer addAnimation:rotateAnimation forKey:nil];
}
CAPropertyAnimation提供的函數(shù)
+ (instancetype)animationWithKeyPath:(nullable NSString *)path;
函數(shù)描述 :使用指定的path描述的屬性創(chuàng)建CAPropertyAnimation實(shí)例率挣,例如使用這一字符串@"position.x"創(chuàng)建CGPoint中心點(diǎn)X軸方向改變位置的CAPropertyAnimation實(shí)例刻伊。
參數(shù) :
path : 描述屬性的字符串。
返回值 : CAPropertyAnimation實(shí)例椒功,并且該實(shí)例的keyPath設(shè)置為path捶箱。
CAKeyframeAnimation - 關(guān)鍵幀動(dòng)畫
CAKeyframeAnimation繼承自CAPropertyAnimation,為CALayer(圖層)對(duì)象提供關(guān)鍵幀動(dòng)畫功能的對(duì)象(在某一時(shí)間段動(dòng)畫進(jìn)行到某一幀)动漾。使用繼承的animationWithKeyPath:方法創(chuàng)建CAKeyframeAnimation對(duì)象非洲,keyPath指定要在圖層上進(jìn)行動(dòng)畫的圖層框架屬性酒唉,然后可以通過指定values和動(dòng)畫計(jì)時(shí)(例如keyTimes)控制動(dòng)畫行為蜜暑。
在動(dòng)畫過程中画恰,Core animation通過插入提供的值來生成中間值,例如當(dāng)為一個(gè)坐標(biāo)點(diǎn)(比如圖層的位置)設(shè)置動(dòng)畫時(shí)键思,可以為這個(gè)點(diǎn)指定一條由values構(gòu)成的路徑础爬,而不是單獨(dú)的值。動(dòng)畫的速度由提供的時(shí)間信息控制吼鳞。
CAKeyframeAnimation提供的屬性
@property(nullable, copy) NSArray *values;
屬性描述 :為CAKeyframeAnimation實(shí)例提供動(dòng)畫功能值的對(duì)象數(shù)組。values表示CAKeyframeAnimation實(shí)例動(dòng)畫必須通過的值叫搁。將給定的values中的值應(yīng)用到添加動(dòng)畫的圖層的時(shí)間取決于動(dòng)畫計(jì)時(shí)赔桌,動(dòng)畫計(jì)時(shí)由calculationMode、keyTimes和timingFunctions屬性控制渴逻。應(yīng)用于CAKeyframeAnimation實(shí)例之間的值是使用插值創(chuàng)建的疾党,除非計(jì)算模式設(shè)置為kCAAnimationDiscrete。
根據(jù)屬性的類型惨奕,可能需要用NSNumber的NSValue對(duì)象包裝這個(gè)數(shù)組中的值雪位。對(duì)于某些核心圖形數(shù)據(jù)類型,可能還需要在將它們添加到數(shù)組之前將它們轉(zhuǎn)換為id梨撞。
此屬性中的值僅在path屬性中的值為nil時(shí)使用雹洗。
@property(nullable) CGPathRef path;
屬性描述 :分配給此屬性的路徑對(duì)象定義了圖層屬性(圖層屬性包含 CGPoint 數(shù)據(jù)類型)在動(dòng)畫長(zhǎng)度上的值香罐。如果為此屬性指定值,則會(huì)忽略 values 屬性中的任何數(shù)據(jù)时肿。
為動(dòng)畫指定的任何計(jì)時(shí)值(keyTimes)都將應(yīng)用于用于創(chuàng)建路徑的點(diǎn)庇茫,路徑可以包含定義移動(dòng)到線段的點(diǎn)(moveToPoint:),以直線添加到線段的點(diǎn)或以曲線添加到線段的點(diǎn)螃成,直線段或曲線段會(huì)在線段的終點(diǎn)定義關(guān)鍵幀值旦签,然后在線段起點(diǎn)(前一條線段的終點(diǎn))與線段終點(diǎn)之間的所有其他的點(diǎn)進(jìn)行插值,以移動(dòng)的方式添加到線段的點(diǎn)不定義單獨(dú)的關(guān)鍵幀值寸宏。
動(dòng)畫沿路徑運(yùn)行的方式取決于calculationMode 屬性中的值宁炫。要實(shí)現(xiàn)沿路徑的平滑、勻速動(dòng)畫氮凝,請(qǐng)將calculationMode 屬性設(shè)置為kCAAnimationPaced 或kCAAnimationCubicPaced淋淀;要?jiǎng)?chuàng)建位置值從關(guān)鍵幀點(diǎn)跳轉(zhuǎn)到關(guān)鍵幀點(diǎn)(中間沒有插值)的動(dòng)畫,請(qǐng)使用 kCAAnimationDiscrete 值覆醇;要通過在點(diǎn)之間插值沿路徑設(shè)置動(dòng)畫朵纷,請(qǐng)使用kCAAnimationLinear值。
@property(copy) CAAnimationCalculationMode calculationMode;
屬性描述 :calculationMode可能的值有“discrete”永脓、“l(fā)inear”袍辞、“paced”、“cubic”和“cubicPaced”常摧。默認(rèn)為“ linear”搅吁。當(dāng)設(shè)置為paced或cubicPaced時(shí),動(dòng)畫的keyTimes和timingFunctions屬性將被忽略并隱式計(jì)算落午。
//關(guān)鍵幀值之間的簡(jiǎn)單線性計(jì)算谎懦。
CA_EXTERN CAAnimationCalculationMode const kCAAnimationLinear
//依次使用每個(gè)關(guān)鍵幀值,不計(jì)算插值溃斋。
CA_EXTERN CAAnimationCalculationMode const kCAAnimationDiscrete
//對(duì)線性關(guān)鍵幀值進(jìn)行插值以在整個(gè)動(dòng)畫中產(chǎn)生均勻的速度界拦。
CA_EXTERN CAAnimationCalculationMode const kCAAnimationPaced
//關(guān)鍵幀值之間的平滑樣條線計(jì)算。梗劫。
CA_EXTERN CAAnimationCalculationMode const kCAAnimationCubic
//對(duì)三次關(guān)鍵幀值進(jìn)行插值以在整個(gè)動(dòng)畫中產(chǎn)生均勻的速度享甸。
CA_EXTERN CAAnimationCalculationMode const kCAAnimationCubicPaced
@property(nullable, copy) NSArray<NSNumber *> *keyTimes;
屬性描述 :應(yīng)用于CAKeyframeAnimation實(shí)例動(dòng)畫的可選數(shù)組(數(shù)組中存放NSNumber對(duì)象),定義了動(dòng)畫的時(shí)間段梳侨,數(shù)組中的每個(gè)值是0.0(起始時(shí)間)到1.0(結(jié)束時(shí)間)之間的浮點(diǎn)數(shù)蛉威,數(shù)組中的每個(gè)后續(xù)值必須大于或等于前一個(gè)值,這些值代表在動(dòng)畫總持續(xù)時(shí)間中的一個(gè)時(shí)間點(diǎn)走哺。通常蚯嫌,數(shù)組中的元素?cái)?shù)量應(yīng)與values屬性中的元素?cái)?shù)量或path屬性中的控制點(diǎn)數(shù)量匹配,如果它們之間是不匹配的,則動(dòng)畫的效果可能不是所期望的择示。
如何在數(shù)組中包含適當(dāng)?shù)闹等Q于calculationMode屬性:
如果calculationMode設(shè)置為kCAAnimationLinear或kCAAnimationCubic束凑,則數(shù)組中的第一個(gè)值必須是0.0,最后一個(gè)值必須是1.0对妄,所有中間值表示開始和結(jié)束時(shí)間之間的時(shí)間點(diǎn)湘今。
如果calculationMode設(shè)置為kCAAnimationDiscrete,則數(shù)組中的第一個(gè)值必須是0.0剪菱,最后一個(gè)值必須是1.0摩瞎,數(shù)組中應(yīng)該比values數(shù)組中多一個(gè)條目。例如孝常,如果values數(shù)組中有兩個(gè)值旗们,那么該有三個(gè)時(shí)間點(diǎn)的值。
如果calculationMode設(shè)置為kCAAnimationPaced或kCAAnimationCubicPaced构灸,則忽略此屬性中的值上渴。
如果此數(shù)組中的值無(wú)效或不適合當(dāng)前計(jì)算模式,則忽略它們喜颁。
@property(nullable, copy) NSArray<CAMediaTimingFunction *> *timingFunctions;
屬性描述 :應(yīng)用于CAKeyframeAnimation實(shí)例動(dòng)畫的可選數(shù)組(數(shù)組中存放CAMediaTimingFunction對(duì)象)稠氮,可以使用此數(shù)組定義values數(shù)組中兩個(gè)值節(jié)點(diǎn)之間的動(dòng)畫節(jié)奏,可以使動(dòng)畫線性過渡半开、或緩慢開始后加速過渡隔披、或加速開始后緩慢過渡。如果values屬性中的元素為n寂拆,則此數(shù)組中元素應(yīng)包含n-1個(gè)對(duì)象奢米。
此屬性通過動(dòng)畫計(jì)時(shí)控制動(dòng)畫節(jié)奏,如果在keyTimes屬性中提供了計(jì)時(shí)信息纠永,則此屬性指定的動(dòng)畫節(jié)奏計(jì)時(shí)將在keyTimes屬性提供的值之間進(jìn)行進(jìn)一步修改鬓长。如果未為keyTimes屬性指定值,則此屬性指定的動(dòng)畫節(jié)奏計(jì)時(shí)將修改動(dòng)畫對(duì)象提供的默認(rèn)計(jì)時(shí)尝江。
如果還在動(dòng)畫對(duì)象的timingFunction屬性中指定動(dòng)畫節(jié)奏計(jì)時(shí)函數(shù)涉波,則會(huì)首先應(yīng)用timingFunction屬性中指定的動(dòng)畫節(jié)奏計(jì)時(shí)函數(shù),然后應(yīng)用特定關(guān)鍵幀時(shí)間段的計(jì)時(shí)函數(shù)茂装。
@property(nullable, copy) CAAnimationRotationMode rotationMode;
屬性描述 :定義沿路徑設(shè)置動(dòng)畫的對(duì)象是否旋轉(zhuǎn)以匹配路徑切線怠蹂,默認(rèn)為nil,可以設(shè)置的值為“auto”和“autoReverse”少态。在為提供路徑對(duì)象時(shí)為此屬性設(shè)置值則行為是為定義的 。易遣。
CAAnimationRotationMode提供的值 :
//物體沿著與路徑相切的方向運(yùn)動(dòng)彼妻。
CA_EXTERN CAAnimationRotationMode const kCAAnimationRotateAuto
//物體以與路徑相切的180度移動(dòng)。
CA_EXTERN CAAnimationRotationMode const kCAAnimationRotateAutoReverse
通過values設(shè)置關(guān)鍵點(diǎn) :
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor = [UIColor blueColor];
[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
button.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[button.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[button.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
]];
self.myView = [[MyView alloc]initWithFrame:CGRectZero];
self.myView.layer.contents = (id)[UIImage imageNamed:@"darts"].CGImage;
[self.view addSubview:self.myView];
self.myView.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[self.myView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[self.myView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
[self.myView.widthAnchor constraintEqualToConstant:100],
[self.myView.heightAnchor constraintEqualToConstant:100],
]];
}
- (void)buttonClick:(UIButton *)sender {
//獲取視圖的中心點(diǎn)X軸坐標(biāo)點(diǎn)
CGFloat myViewCenterX = self.myView.center.x;
//初始化在中心點(diǎn)在X軸坐標(biāo)移動(dòng)的關(guān)鍵幀動(dòng)畫
CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"position.x"];
//動(dòng)畫持續(xù)時(shí)間
animation.duration = 5.0f;
//動(dòng)畫的5個(gè)關(guān)鍵點(diǎn)
animation.values = @[@(myViewCenterX),@(myViewCenterX - 150),@(myViewCenterX),@(myViewCenterX + 150),@(myViewCenterX)];
//動(dòng)畫到達(dá)5個(gè)關(guān)鍵點(diǎn)的時(shí)間節(jié)點(diǎn)
animation.keyTimes = @[@0,@0.25,@0.50,@0.75,@1];
//在每?jī)蓚€(gè)時(shí)間節(jié)點(diǎn)之間的動(dòng)畫節(jié)奏
animation.timingFunctions = @[
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
//添加動(dòng)畫
[self.myView.layer addAnimation:animation forKey:nil];
}
代碼效果 :
通過path設(shè)置路徑 :
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor = [UIColor blueColor];
[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
button.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[button.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[button.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
]];
self.myView = [[MyView alloc]initWithFrame:CGRectZero];
self.myView.layer.contents = (id)[UIImage imageNamed:@"darts"].CGImage;
[self.view addSubview:self.myView];
self.myView.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[self.myView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[self.myView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
[self.myView.widthAnchor constraintEqualToConstant:100],
[self.myView.heightAnchor constraintEqualToConstant:100],
]];
}
- (void)buttonClick:(UIButton *)sender {
//曲線
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(CGRectGetMidX(self.view.frame) - 200 / 2, CGRectGetMidY(self.view.frame) - 150 / 2, 200, 150)];
//形狀層
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
//路徑形狀填充顏色
shapeLayer.fillColor = nil;
//路徑的線寬
shapeLayer.lineWidth = 2.5f;
//路徑顏色
shapeLayer.strokeColor = [UIColor blueColor].CGColor;
//渲染的形狀的路徑
shapeLayer.path = path.CGPath;
//添加形狀層
[self.view.layer addSublayer:shapeLayer];
CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
animation.path = path.CGPath;
//動(dòng)畫持續(xù)時(shí)間
animation.duration = 5.0f;
//動(dòng)畫運(yùn)行方式
animation.calculationMode = kCAAnimationCubicPaced;
//動(dòng)畫重復(fù)次數(shù)
animation.repeatCount = HUGE_VALF;
//自動(dòng)旋轉(zhuǎn)匹配切線
animation.rotationMode = kCAAnimationRotateAuto;
//添加動(dòng)畫
[self.myView.layer addAnimation:animation forKey:nil];
}
代碼效果 :
CABasicAnimation -- 基本的單一關(guān)鍵幀動(dòng)畫
繼承自CAPropertyAnimation,為圖層(CALayer)的屬性提供基本的單一關(guān)鍵幀動(dòng)畫功能的對(duì)象侨歉。使用繼承的animationWithKeyPath:方法創(chuàng)建CABasicAnimation的實(shí)例屋摇,并在關(guān)鍵路徑(KeyPath)中指定要在渲染樹中添加動(dòng)畫的屬性的。例如:[CABasicAnimation animationWithKeyPath:@"transform.rotation"]描述了了一個(gè)旋轉(zhuǎn)動(dòng)畫幽邓。
以下是定義在其間插值的屬性值的對(duì)象炮温,所有選項(xiàng)都是可選的,而且非nil的屬性不應(yīng)該超過兩個(gè)牵舵,對(duì)象類型應(yīng)該與被動(dòng)畫的屬性類型相匹配(使用CALayer.h中描述的標(biāo)準(zhǔn)規(guī)則)柒啤。支持的動(dòng)畫模式有:
“fromValue”和“toValue”都不為nil,在fromValue和toValue之間進(jìn)行插值畸颅。
“fromValue”和“byValue”不為nil担巩,在“fromValue”和“fromValue”加上“byValue”之間進(jìn)行插值。
“byValue”和“toValue”不為nil没炒,在“toValue”減去“byValue”和“toValue”之間進(jìn)行插值涛癌。
“fromValue”非nil,在“fromValue”和屬性的當(dāng)前表示值之間進(jìn)行插值送火。
“toValue”非nil拳话,在渲染樹中圖層的當(dāng)前屬性值和“toValue”之間進(jìn)行插值。
“byValue”非nil种吸,在渲染樹中圖層的當(dāng)前屬性值和加上“byValue”的值之間進(jìn)行插值弃衍。
CABasicAnimation的屬性
@property(nullable, strong) id fromValue;
屬性描述 : 定義調(diào)用方用于開始插值的值。
@property(nullable, strong) id toValue;
屬性描述 : 定義調(diào)用方用于結(jié)束插值的值骨稿。
@property(nullable, strong) id byValue;
屬性描述 : 定義調(diào)用方用于執(zhí)行相對(duì)插值的值笨鸡。
- (void)viewDidLoad {
[super viewDidLoad];
// 設(shè)置視圖
UIView *view = [[UIView alloc]initWithFrame:CGRectZero];
view.backgroundColor = [UIColor redColor];
[self.view addSubview:view];
view.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[view.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[view.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
[view.widthAnchor constraintEqualToConstant:100],
[view.heightAnchor constraintEqualToConstant:100],
]];
// 設(shè)置動(dòng)畫為旋轉(zhuǎn)
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
// 動(dòng)畫持續(xù)時(shí)間
animation.duration = 5.0f;
// 重復(fù)次數(shù)(HUGE_VALF為無(wú)限重復(fù))
animation.repeatCount = HUGE_VALF;
// 開始時(shí)的位置
animation.fromValue = [NSNumber numberWithFloat:0];
// 結(jié)束時(shí)的位置
animation.toValue = [NSNumber numberWithFloat:M_PI * 2];
// 添加動(dòng)畫
[view .layer addAnimation:animation forKey:nil];
}
簡(jiǎn)單的旋轉(zhuǎn):
對(duì)keypath提供的簡(jiǎn)單動(dòng)畫的效果的匯總
//CATransform3D Key Paths
static NSString *kCARotation = @"transform.rotation"; //旋轉(zhuǎn)
static NSString *kCARotationX = @"transform.rotation.x"; //圍繞X軸旋轉(zhuǎn)
static NSString *kCARotationY = @"transform.rotation.y"; //圍繞Y軸旋轉(zhuǎn)
static NSString *kCARotationZ = @"transform.rotation.z"; //圍繞Z軸旋轉(zhuǎn)
//縮放
static NSString *kCAScale = @"transform.scale"; //縮放
static NSString *kCAScaleX = @"transform.scale.x"; //對(duì)X方向進(jìn)行縮放
static NSString *kCAScaleY = @"transform.scale.y"; //對(duì)Y方向進(jìn)行縮放
static NSString *kCAScaleZ = @"transform.scale.z"; //對(duì)Z方向進(jìn)行縮放
//平移
static NSString *kCATranslation = @"transform.translation"; //平移
static NSString *kCATranslationX = @"transform.translation.x"; //對(duì)X方向進(jìn)行平移
static NSString *kCATranslationY = @"transform.translation.y"; //對(duì)Y方向進(jìn)行平移
static NSString *kCATranslationZ = @"transform.translation.z"; //對(duì)Z方向進(jìn)行平移
//平面
static NSString *kCAPosition = @"position"; //CGPoint中心點(diǎn)改變位置
static NSString *kCAPositionX = @"position.x"; //CGPoint中心點(diǎn)X方向改變位置
static NSString *kCAPositionY = @"position.y"; //CGPoint中心點(diǎn)Y方向改變位置
//CGRect
static NSString *kCABoundsSize = @"bounds.size"; //自身界限的大小
static NSString *kCABoundsSizeW = @"bounds.size.width"; //自身界限的寬度
static NSString *kCABoundsSizeH = @"bounds.size.height"; //自身界限的高度
static NSString *kCABoundsOriginX = @"bounds.origin.x"; //自身界限的起點(diǎn)X方向
static NSString *kCABoundsOriginY = @"bounds.origin.y"; //自身界限的起點(diǎn)Y方向
//Layer
static NSString *kCAOpacity = @"opacity"; //透明度
static NSString *kCABackgroundColor = @"backgroundColor"; //背景色
static NSString *kCACornerRadius = @"cornerRadius"; //圓角
static NSString *kCABorderWidth = @"borderWidth"; //邊框
static NSString *kCAShadowColor = @"shadowColor"; //陰影顏色
static NSString *kCAShadowOffset = @"shadowOffset"; //偏移量CGSize
static NSString *kCAShadowOpacity = @"shadowOpacity"; //陰影透明度
static NSString *kCAShadowRadius = @"shadowRadius"; //陰影圓角
CASpringAnimation - 彈簧力動(dòng)畫
CASpringAnimation繼承自CABasicAnimation,對(duì)層的屬性應(yīng)用類似彈簧力的動(dòng)畫坦冠。通常使用彈簧動(dòng)畫設(shè)置層位置的動(dòng)畫形耗,使其看起來被彈簧拉向目標(biāo)。層離目標(biāo)越遠(yuǎn)辙浑,對(duì)它的加速度就越大激涤。CASpringAnimation允許控制基于物理的屬性,例如彈簧的阻尼和剛度判呕。
CASpringAnimation提供的屬性
@property CGFloat mass;
屬性描述 : 附著在彈簧末端的物體的質(zhì)量倦踢,默認(rèn)質(zhì)量為1。增加該值將增加彈簧彈力效果侠草,附加與彈簧動(dòng)畫的對(duì)象將受到更多的振蕩次數(shù)和更大的彈力回調(diào)辱挥,從而增加動(dòng)畫沉降過程持續(xù)時(shí)間;減小該值將減少?gòu)椈闪πЧ咛椋袷幋螖?shù)與彈力回調(diào)減少晤碘,從而減少動(dòng)畫沉降過程持續(xù)時(shí)間褂微。
@property CGFloat stiffness;
屬性描述 :彈簧動(dòng)畫彈簧的剛度系數(shù),默認(rèn)的剛度系數(shù)為100园爷。增加剛度可增加振蕩次數(shù)宠蚂,并增加動(dòng)畫沉降過程持續(xù)時(shí)間;減小剛度會(huì)減少振蕩次數(shù)童社,并減少動(dòng)畫沉降過程持續(xù)時(shí)間求厕。
@property CGFloat damping;
屬性描述 :抑制彈簧彈力的阻尼值,默認(rèn)值是10扰楼。減少這個(gè)值可以減少每次振蕩的能量損失呀癣,動(dòng)畫值將超過toValue,并且使動(dòng)畫沉降過程持續(xù)時(shí)間大于動(dòng)畫持續(xù)時(shí)間灭抑。增加數(shù)值會(huì)增加能量損耗十艾,振蕩會(huì)越來越少,越來越小腾节,動(dòng)畫沉降過程持續(xù)時(shí)間可能會(huì)小于動(dòng)畫持續(xù)時(shí)間忘嫉。
@property CGFloat initialVelocity;
屬性描述 :附著在彈簧上的物體的初始速度,默認(rèn)為0案腺,表示不移動(dòng)的對(duì)象庆冕。負(fù)值表示附著在彈簧上對(duì)象先反向遠(yuǎn)離彈簧連接點(diǎn),正值表示附著在彈簧上對(duì)象加速在彈簧附著點(diǎn)正向移動(dòng)劈榨。
@property(readonly) CFTimeInterval settlingDuration;
屬性描述 :彈簧系統(tǒng)返回到靜止時(shí)要考慮的所需的估計(jì)持續(xù)時(shí)間访递,將為當(dāng)前動(dòng)畫參數(shù)計(jì)算持續(xù)時(shí)間。
@interface TSChannelFiveViewController ()<CAAnimationDelegate>
@property (nonatomic, strong) UIView *myView;
@property (nonatomic, strong) NSLayoutConstraint *myViewYConstraint;
@end
@implementation TSChannelFiveViewController
- (void)viewDidLoad {
[super viewDidLoad];
//設(shè)置按鈕
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor = [UIColor blueColor];
[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
button.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[button.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[button.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
]];
// 設(shè)置視圖
self.myView = [[UIView alloc]initWithFrame:CGRectZero];
self.myView.backgroundColor = [UIColor redColor];
[self.view addSubview:self.myView];
UITapGestureRecognizer *singleClick = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(singleClickEvent)];
[self.myView addGestureRecognizer:singleClick];
self.myView.translatesAutoresizingMaskIntoConstraints = NO;
self.myViewYConstraint = [self.myView.bottomAnchor constraintEqualToAnchor:self.view.topAnchor];
[NSLayoutConstraint activateConstraints:@[
[self.myView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
self.myViewYConstraint,
[self.myView.widthAnchor constraintEqualToConstant:100],
[self.myView.heightAnchor constraintEqualToConstant:100],
]];
}
/// 按鈕點(diǎn)擊事件
- (void)buttonClick:(UIButton *)button {
// 設(shè)置動(dòng)畫為旋轉(zhuǎn)
CASpringAnimation * animation = [CASpringAnimation animationWithKeyPath:@"position.y"];
animation.delegate = self;
// 動(dòng)畫持續(xù)時(shí)間
animation.duration = 2.0f;
// 結(jié)束時(shí)的位置
animation.toValue = @(CGRectGetMidY(self.view.frame));
// 附著在彈簧上的物體質(zhì)量
animation.mass = 3;
// 彈簧剛度
animation.stiffness = 300;
// 彈簧彈力的阻尼
animation.damping = 9;
// 使視圖停留在動(dòng)畫結(jié)束的位置
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
// 添加動(dòng)畫
[self.myView.layer addAnimation:animation forKey:nil];
}
/// 視圖點(diǎn)擊事件
- (void)singleClickEvent {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"點(diǎn)擊了" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:cancelAction];
[self presentViewController:alert animated:YES completion:nil];
}
#pragma mark - CAAnimationDelegate
/// 動(dòng)畫結(jié)束
/// @param anim 結(jié)束的動(dòng)畫對(duì)象
/// @param flag 指示動(dòng)畫是否因?yàn)檫_(dá)到其活動(dòng)持續(xù)時(shí)間后而結(jié)束的標(biāo)志
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
if (flag) {
self.myViewYConstraint.active = NO;
self.myViewYConstraint = [self.myView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor];
self.myViewYConstraint.active = YES;
}
}
@end
在動(dòng)畫結(jié)束后更新了一下約束同辣,因?yàn)閷釉趧?dòng)畫完成后拷姿,雖然視圖保留了動(dòng)畫完成時(shí)的位置,但視圖的frame實(shí)際是沒有改變的旱函,如果沒有更新約束响巢,視圖是不響應(yīng)點(diǎn)擊事件的,因?yàn)楦緵]有點(diǎn)擊到視圖上棒妨。效果如圖: