相關(guān)或者無關(guān)的
layer
Layers Provide the Basis for Drawing and Animations(Layers是繪圖和動畫的基礎(chǔ))
Layer是在3D空間中的2D平面,管理幾何(例如rotate谋国,transform)槽地,內(nèi)容(image等),和可視屬性(backgroundColor芦瘾,alpha)等信息捌蚊。因?yàn)閳D層主要用來管理數(shù)據(jù),可以看作對象模型近弟,
由于基于Layer的繪制是處理靜態(tài)的Bitmap的缅糟,而bitmap的處理又是GPU所擅長的,所以它的效率要比基于View繪制的高很多祷愉,因?yàn)榛赩iew繪制的每次都要進(jìn)行drawRect的調(diào)用重新繪制窗宦。
大部分圖層,捕獲顯示的內(nèi)容并緩存它們到位圖中二鳄。位圖有時(shí)也被稱為儲備(backing store)赴涵。當(dāng)你改變了一個(gè)圖層的屬性值,只是改變了與圖層對象相關(guān)聯(lián)的狀態(tài)信息订讼。當(dāng)更改觸發(fā)了一個(gè)動畫句占,Core Animation會將該圖層的位圖數(shù)據(jù)和狀態(tài)信息發(fā)送給圖形處理硬件。圖形處理器所做的工作是根據(jù)獲得的信息對位圖進(jìn)行渲染躯嫉,用圖形處理硬件操縱位圖要比圖形處理軟件能獲得更好的動畫效果。
因?yàn)椴倏v的是靜態(tài)的位圖杨拐,基于Layer的繪圖和基于View的繪圖在技術(shù)上有明顯的不同祈餐。
基于View的繪圖,對View的改變經(jīng)常會觸發(fā)視圖的
drawRect:
方法以重繪視圖內(nèi)容哄陶。但代價(jià)相對較高帆阳,因?yàn)樗荂PU在主線程上的操作。Core Animation盡可能使用圖形硬件操縱緩存后的位圖來避免了這種開銷,從而完成相同或相似的效果蜒谤。雖然盡可能使用緩存內(nèi)容山宾,但也必須提供初始內(nèi)容并不時(shí)地進(jìn)行內(nèi)容更新。
圖層對象定義了自己的幾何結(jié)構(gòu)
圖層的一項(xiàng)任務(wù)是管理自身內(nèi)容的幾何結(jié)構(gòu)鳍徽。包含內(nèi)容的邊界bound资锰、在屏幕上的位置origin,是否已被旋轉(zhuǎn)阶祭、縮放绷杜,或應(yīng)用了某種變換。圖層有frame和bound屬性來定位圖層和它的內(nèi)容濒募。也有一些View所沒有的屬性鞭盟,比如anchorPoint
屬性,任何變換操作都是圍繞該點(diǎn)運(yùn)轉(zhuǎn)的
圖層可在三維空間中操作
Layer有兩個(gè)操控圖層和內(nèi)容的變換矩陣瑰剃,transform
和sublayerTransform
屬性齿诉。
transform指定應(yīng)用到圖層和它內(nèi)嵌的子層上的變換。當(dāng)你想更改圖層本身則使用該屬性晌姚。
比方說粤剧,使用該屬性縮放或旋轉(zhuǎn)圖層,或臨時(shí)的改變圖層的位置舀凛。sublayerTransform屬性定義了僅應(yīng)用在子層上的變換以及給場景內(nèi)容添加透視效果俊扳。
layer內(nèi)容
圖層是管理app內(nèi)容的數(shù)據(jù)對象森缠。圖層的內(nèi)容由包含可視數(shù)據(jù)的位圖構(gòu)成遥金。使用下述三種方式之一可給提供圖層的內(nèi)容:
- 直接賦值一個(gè)UIImage對象給圖層對象contents屬性缨恒。(這個(gè)技術(shù)適用于圖層內(nèi)容從不或幾乎不改變的情形恋博。)圖片類型必須是CGImageRef類型,對于Retina顯示設(shè)備吨凑,這可能也需要你去調(diào)整layer的contentsScale屬性袁勺。使用[[UIScreen mainScreen] scale]可獲取正確的縮放率儿子。
- 賦值一個(gè)代理給圖層郑原,由代理負(fù)責(zé)繪制圖層內(nèi)容腌紧。(該技術(shù)適用于圖層內(nèi)容可能偶爾改變茸习,且內(nèi)容可由外部對象提供,比如視圖壁肋。)
代理方法:
@protocol CALayerDelegate <NSObject>
@optional
- (void)displayLayer:(CALayer *)layer;
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;
- (void)layerWillDraw:(CALayer *)layer
API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0));
- (void)layoutSublayersOfLayer:(CALayer *)layer;
- (nullable id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event;
@end
// displayLayer:如果代理實(shí)現(xiàn)了這個(gè)方法号胚,那么要繪制一個(gè)bitmap,然后賦值給contents屬性
-(void)displayLayer:(CALayer *)layer
{
NSString * imageName = @"temp";
layer.contents = (id)[UIImage imageNamed:imageName].CGImage;
}
@end
//drawLayer:inContext:如果代理實(shí)現(xiàn)了這個(gè)方法浸遗,Core Animation提供一個(gè)context來生成bitmap猫胁,你所做的只是把想要的內(nèi)容繪制到context
-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddArc(path,NULL,100,100,95,0,M_PI*2, YES);
CGContextBeginPath(ctx);
CGContextAddPath(ctx,path);
CGContextSetLineWidth(ctx, 5);
CGContextStrokePath(ctx);
CFRelease(path);
}
- 定義一個(gè)CALayer的子類并覆蓋類的繪圖方法,有覆蓋的方法返回圖層的內(nèi)容跛锌。(該技術(shù)適用于你需要?jiǎng)?chuàng)建自定義圖層的子類弃秆,或者你想改變圖層基本的繪圖行為。)
3.1 覆蓋圖層的display
方法并使用在方法中直接設(shè)置圖層的contents
屬性。
3.2 覆蓋圖層的drawInContext:
方法并將需要的內(nèi)容繪制到提供的圖形上下文中菠赚。
Layer Tree圖層樹
Layer Tree分為三種脑豹,
Model Layer Tree
:樹中的對象是模型對象,模型對象存儲所有動畫的目標(biāo)值衡查。無論何時(shí)改變圖層的屬性值瘩欺,你使用的始終是某一個(gè)模型對象。比如layer.position = CGPointMake(10.0,10.0)修改的就是Model Layer Tree
Presentation Tree
:包含所有運(yùn)行中的動畫的瞬時(shí)值峡捡。代表顯示在屏幕上動畫的當(dāng)前值击碗。你不應(yīng)該更改這個(gè)樹中的對象。而是讀取當(dāng)前動畫的值们拙,可以創(chuàng)建開始于這些值的新的動畫稍途。
Render Tree
:Render Tree中的對象執(zhí)行實(shí)際的動畫,為CoreAnimation私有的砚婆,是CoreAnimation實(shí)現(xiàn)使用的私有Tree械拍,
通過-[CALayer presentationLayer]
和-[CALayer modelLayer]
可以訪問兩種Tree
上述三種Tree的對應(yīng)關(guān)系如下圖
常用的Layer子類
CAEmitterLayer | 發(fā)射器層,用來控制粒子效果 |
CAGradientLayer | 梯度層装盯,顏色漸變 |
CAEAGLLayer | 用OpenGL ES繪制的層 |
CAReplicationLayer | 用來自動復(fù)制sublayer |
CAScrollLayer | 用來管理可滑動的區(qū)域 |
CAShapeLayer | 繪制立體的貝塞爾曲線 |
CATextLayer | 可以繪制AttributeString |
CATiledLayer | 用來管理一副可以被分割的大圖 |
CATransformLayer | 用來渲染3D layer的層次結(jié)構(gòu) |
position 和 anchorPoint
anchorPoint
:錨點(diǎn)(對layer動畫有很大影響)
position
: 錨點(diǎn)在superLayer中的位置
視圖的center屬性和圖層的position屬性指定了anchorPoint相對父圖層的位置坷虑。
默認(rèn)anchorPoint值是(0.5,0.5)埂奈,位于圖層的中點(diǎn)迄损,圖層以這個(gè)點(diǎn)為中心放置,
當(dāng)改變frame時(shí),position(center)會改變账磺。
當(dāng)改變position(center)時(shí)芹敌,frame會改變。
當(dāng)改變frame時(shí)垮抗,archorPoint不變氏捞。
當(dāng)改變archorPoint時(shí),frame隨之改變
[self.tmpView setFrame:CGRectMake(50, 60, 70, 80)];
/*
frame:{{50, 60}, {70, 80}},center:{85, 100},position:{85, 100},anchorPoint:{0.5, 0.5}
*/
self.tmpView.layer.anchorPoint = CGPointMake(0, 0);
/*
frame:{{85, 100}, {70, 80}},center:{85, 100},position:{85, 100},anchorPoint:{0, 0}
*/
當(dāng)圖層做旋轉(zhuǎn)操作時(shí)冒版,會圍繞著anchorPoint對應(yīng)的點(diǎn)旋轉(zhuǎn),并且任何你對圖層陰影的變換操作也是相對于anchorPoint液茎。
frame
frame是一個(gè)派生屬性,根據(jù)layer的bounds辞嗡,position(center)捆等,archorPoint,transform計(jì)算.
當(dāng)改變bounds续室,position(center)栋烤,archorPoint,transform當(dāng)中的任何一個(gè)值時(shí)猎贴,frame都會發(fā)生變化。
當(dāng)變換后的frame是一個(gè)平行四邊形或者不平行與邊軸時(shí),返回一個(gè)最小的包括變換后的frame的四個(gè)頂點(diǎn)的矩形她渴,這個(gè)矩形就是frame达址。
當(dāng)改變frame時(shí),archorPoint趁耗,transform不變沉唠,bounds和position(center)隨之改變。
bounds
通過get和set方法苛败,直接讀取layer的bounds屬性满葛。
當(dāng)改變frame的size時(shí),bounds會改變罢屈。
當(dāng)改變bounds的size時(shí)嘀韧,frame隨之改變
修改bounds.x/y不會影響該View在父View中的位置,但是會影響該View子View的位置
比如如果設(shè)置為-20,-20缠捌,則使得坐標(biāo)系的(0锄贷,0)原點(diǎn)相對于原來向左下偏移20個(gè)單位
view的transform
view的transform屬性是直接調(diào)用的layer的affineTransform屬性的get和set方法。affineTransform實(shí)際上是一個(gè)計(jì)算屬性曼月,當(dāng)layer調(diào)用affineTransform的set方法時(shí)谊却,實(shí)際上是換算為CATransform3D類型的結(jié)構(gòu)體賦值給layer的transform屬性。
同理調(diào)用affineTransform的get方法時(shí)哑芹,也是通過layer的transform屬性換算為 CGAffineTransform返回的炎辨。
view的transform屬性等同于layer的affineTransform屬性,是通過get和set方法取的layer的transform的值聪姿。
當(dāng)改變frame時(shí)碴萧,transform不變。
當(dāng)改變transform時(shí)咳燕,frame隨之改變
Core Animation 核心動畫
Core Animation是iOS平臺上負(fù)責(zé)圖形渲染與動畫的基礎(chǔ)設(shè)施勿决。只需配置少量的動畫參數(shù)(如開始點(diǎn)位置和結(jié)束點(diǎn)的位置)即可施展Core Animation魔法。Core Animation將大部分繪圖任務(wù)交給了圖形硬件招盲,圖形硬件會加速圖形渲染的速度低缩。這種自動化的圖形加速技術(shù)讓動畫擁有更高的幀率并且更加的平滑,而且不會加重CPU的負(fù)擔(dān)曹货。
如下圖所示咆繁,Core Animation位于AppKit和UIKit的底層。Core Animation保留了部分用于擴(kuò)展其功能的的接口暴露給了應(yīng)用的視圖顶籽。使用這些接口能更細(xì)粒度地控制應(yīng)用中的動畫玩般。
Core Animation自身并不是一個(gè)繪圖系統(tǒng)。它只是一個(gè)負(fù)責(zé)在硬件上合成和操縱應(yīng)用內(nèi)容的基礎(chǔ)構(gòu)件礼饱。其核心是Layer對象坏为,Layer對象用于管理和操控應(yīng)用內(nèi)容究驴。會將捕獲的內(nèi)容放到一副位圖中。
更改圖層屬性會產(chǎn)生動畫
使用Core Animation創(chuàng)建的大部分動畫都包含對圖層屬性的配置:frame匀伏、origin洒忧、size、opacity够颠、transform熙侍,backgroundColor以及其他面向可視的屬性。
基于圖層的動畫
圖層的位圖數(shù)據(jù)和狀態(tài)信息從圖層內(nèi)容的可視呈現(xiàn)中被分離履磨。舊的屬性值動畫到新的屬性值的過程中蛉抓,分離性給了Core Animation介入此過程的機(jī)會。
例如:改變position會引起Core Animation將圖層從當(dāng)前的位置移動到新的具體位置剃诅。對其他屬性做相似的改變將引起適當(dāng)?shù)膭赢嬓Ч?br>
動畫期間巷送,Core Animation使用硬件幫你完成繪畫每一幀的工作。你只需要指定動畫的開始點(diǎn)和結(jié)束點(diǎn)综苔,如若需要惩系,也可以指定自定義信息(比如動畫運(yùn)行多久)和動畫參數(shù),如果你沒有指定如筛, Core Animation會提供適當(dāng)?shù)哪J(rèn)值堡牡。
隱式動畫
Core Animation將圖層對象屬性的變化當(dāng)做是一個(gè)觸發(fā)器,用以創(chuàng)建和安排一個(gè)或多個(gè)可執(zhí)行的隱式動畫杨刨。大部分屬性的值發(fā)生了變化都將引起Core Animation為你創(chuàng)建動畫對象晤柄,動畫對象將被安排在下一次更新周期運(yùn)行。
theLayer.opacity = 0.0;
顯式動畫
可以顯式地使用動畫對象呈現(xiàn)相同的變化妖胀,創(chuàng)建一個(gè)CAAnimation的子類對象并配置該對象的動畫參數(shù)芥颈。在添加動畫到圖層之前,指定動畫屬性的鍵路徑赚抡,接著設(shè)置動畫參數(shù):動畫的開始值與結(jié)束值爬坑,改變持續(xù)時(shí)間,或任何其他動畫參數(shù)涂臣。為了執(zhí)行一個(gè)動畫盾计,你使用addAnimation:forKey:
方法將動畫對象添加到你想要展現(xiàn)動畫的圖層上。
CABasicAnimation* fadeAnimation = [CABasicAnimation animationWithKeyPath:@”opacity”;
fadeAnimation.fromValue = [NSNumber numberWithFloat:1.0];
fadeAnimation.toValue = [NSNumber numberWithFloat:0.0];
fadeAnimation.duration = 1.0;
[theLayer addAnimation:fadeAnimation forKey:nil];
//改變圖層實(shí)際的最后數(shù)據(jù)值
theLayer.opacity = 0.0; // 記得更新圖層樹
不同于隱式動畫赁遗,隱式動畫會更新圖層對象的值署辉。而顯示動畫不會更改圖層樹中的數(shù)據(jù)。顯示動畫僅是創(chuàng)建了一個(gè)動畫岩四。如果想讓顯示動畫的改變成為永久性的哭尝,必須更新圖層屬性。
CAAnimation
CAAnimation是所有動畫對象的父類剖煌,實(shí)現(xiàn)CAMediaTiming協(xié)議,是一個(gè)抽象類材鹦,不能直接使用逝淹。
CAMediaTiming:負(fù)責(zé)控制動畫的時(shí)間、速度和時(shí)間曲線等等创橄,
/*
如果animation在animation group中,則beginTime就是其parent object——animation group 開始的一個(gè)偏移莽红。eg: beginTime為5,則在group aniamtion開始之后的5s開始動畫邦邦。
如果animation直接添加在layer(layer也遵守CAMediaTiming協(xié)議)beginTime同樣是parent object——layer 開始的一個(gè)偏移安吁,但layer的beginTime是一個(gè)過去的時(shí)間(可能是其被添加到layer tree的時(shí)間),不能簡單設(shè)置beginTime為5,去延遲動畫5s燃辖,有可能layer的beginTime加上5s也是過去的時(shí)間鬼店,當(dāng)延遲一個(gè)添加到layer上的動畫的時(shí)候,需要獲得layer的時(shí)間 `animation.beginTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil] + delay;`
*/
@property CFTimeInterval beginTime;
@property CFTimeInterval duration; // 動畫時(shí)間
@property float speed; // 速度黔龟,如果一個(gè)動畫A :duration為1秒妇智,speed為1;而另一個(gè)動畫B:duration為2秒氏身,speed為2巍棱。則兩個(gè)動畫的時(shí)間是相同的。不過前提是它們的super layer相同蛋欣。
/* 活動本地時(shí)間的其他偏移量航徙。 從父時(shí)間tp轉(zhuǎn)換為活動本地時(shí)間t:t =(tp-開始)*speed+timeOffset。 一種用法是通過將“speed”設(shè)置為零并將“timeOffset”設(shè)置為合適的值來“暫拖莼ⅲ”動畫到踏。 */
@property CFTimeInterval timeOffset;
@property float repeatCount; // 重復(fù)count
@property CFTimeInterval repeatDuration;
@property BOOL autoreverses; // 如果為true,則對象在向前播放后向后播放尚猿。
/*
kCAFillModeRemoved 是默認(rèn)值窝稿,也就是說當(dāng)動畫開始前和動畫結(jié)束后,動畫對layer都沒有影響凿掂,動畫結(jié)束后伴榔,layer會恢復(fù)到之前的狀態(tài)
kCAFillModeForwards 當(dāng)動畫結(jié)束后,layer會一直保持著動畫最后的狀態(tài)
kCAFillModeBackwards 在動畫開始前缠劝,只需要將動畫加入了一個(gè)layer潮梯,layer便立即進(jìn)入動畫的初始狀態(tài)并等待動畫開始。
kCAFillModeBoth 這個(gè)其實(shí)就是上面兩個(gè)的合成.動畫加入后開始之前惨恭,layer便處于動畫初始狀態(tài)秉馏,動畫結(jié)束后layer保持動畫最后的狀態(tài)
*/
@property(copy) CAMediaTimingFillMode fillMode;
CAAnimation提供的屬性和方法
/*
速度控制函數(shù)(CAMediaTimingFunction)
kCAMediaTimingFunctionLinear(線性):勻速,給你一個(gè)相對靜態(tài)的感覺
kCAMediaTimingFunctionEaseIn(漸進(jìn)):動畫緩慢進(jìn)入脱羡,然后加速離開
kCAMediaTimingFunctionEaseOut(漸出):動畫全速進(jìn)入萝究,然后減速的到達(dá)目的地
kCAMediaTimingFunctionEaseInEaseOut(漸進(jìn)漸出):動畫緩慢的進(jìn)入免都,中間加速,然后減速的到達(dá)目的地帆竹。這個(gè)是默認(rèn)的動畫行為绕娘。
*/
@property(nullable, strong) CAMediaTimingFunction *timingFunction;
@property(nullable, strong) id <CAAnimationDelegate> delegate;
//默認(rèn)為YES,代表動畫執(zhí)行完畢后就從圖層上移除栽连,圖形會恢復(fù)到動畫執(zhí)行前的狀態(tài)险领。如果想讓圖層保持顯示動畫執(zhí)行后的狀態(tài),那就設(shè)置為NO秒紧,不過還要設(shè)置fillMode為kCAFillModeForwards
@property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;
@protocol CAAnimationDelegate <NSObject>
@optional
// 動畫已經(jīng)開始
- (void)animationDidStart:(CAAnimation *)anim;
// 當(dāng)動畫結(jié)束或從即圖層中移除時(shí)調(diào)用绢陌。 如果有效持續(xù)時(shí)間結(jié)束時(shí)沒有被刪除,則“ flag”為true熔恢。
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
@end
CAPropertyAnimation
是CAAnimation的子類脐湾,也是個(gè)抽象類,要想創(chuàng)建動畫對象叙淌,應(yīng)該使用它的子類.
/* 創(chuàng)建一個(gè)新的動畫對象秤掌,其“ keyPath”屬性設(shè)置為“ path”。*/
+ (instancetype)animationWithKeyPath:(nullable NSString *)path;
/*
描述要設(shè)置動畫的屬性鹰霍。
通過指定CALayer的一個(gè)屬性名稱為keyPath,并且對這個(gè)屬性值修改闻鉴,達(dá)到相應(yīng)的動畫效果
*/
@property(nullable, copy) NSString *keyPath;
//該屬性指定該屬性動畫是否以當(dāng)前動畫效果為基礎(chǔ)。
@property(getter=isAdditive) BOOL additive;
//該屬性指定動畫是否為累加效果茂洒。
@property(getter=isCumulative) BOOL cumulative;
//該屬性值是一個(gè)CAValueFunction對象椒拗,該對象負(fù)責(zé)對屬性改變的插值計(jì)算,系統(tǒng)已經(jīng)提供了默認(rèn)的插值計(jì)算方式获黔,因此一般無須指定該屬性蚀苛。
@property(nullable, strong) CAValueFunction *valueFunction;
CABasicAnimation
/ *定義要插值的屬性值的對象。
*所有都是可選的玷氏,并且最多不能為兩個(gè)堵未。 對象類型應(yīng)與要設(shè)置動畫的屬性的類型匹配(使用CALayer.h中描述的標(biāo)準(zhǔn)規(guī)則)。 支持的動畫模式為:
*
*-“ fromValue”和“ toValue”均為非零盏触。 在“ fromValue”和“ toValue”之間插值渗蟹。
*-`fromValue'和`byValue'非零。 在'fromValue'和'fromValue'加上`byValue'之間進(jìn)行插值赞辩。
*-“ byValue”和“ toValue”非零雌芽。 在“ toValue”減去“ byValue”和“ toValue”之間進(jìn)行插值俄认。
*-`fromValue'非零曙博。 在`fromValue'和屬性的當(dāng)前表示值之間進(jìn)行插值。
*-“ toValue”非零昌犹。 在渲染樹中圖層的當(dāng)前屬性值和“ toValue”之間進(jìn)行插值糟需。
*-`byValue'非零屉佳。 在渲染樹中該圖層的當(dāng)前屬性值與加“ byValue”的值之間進(jìn)行插值谷朝。 * /
@property(nullable, strong) id fromValue; // 開始插值的值。
@property(nullable, strong) id toValue;// 結(jié)束插值的值武花。
@property(nullable, strong) id byValue; // 相對插值的值圆凰。
CAKeyframeAnimation
//表示動畫執(zhí)行的各個(gè)值(各個(gè)動作)
@property(nullable, copy) NSArray *values;
/*
基于CGPoint的屬性要遵循的路徑(比如圖層的anchorPoint屬性和position屬性)
。當(dāng)為非nil的時(shí)候覆蓋“values”屬性体箕,它默認(rèn)為nil专钉。表示以恒定的速度沿著路徑進(jìn)行動畫,
動畫沿路徑進(jìn)行的方式取決于CalculationMode屬性中的值
*/
@property(nullable) CGPathRef path;
/* 定義動畫執(zhí)行過程中每個(gè)值速度累铅,與values這個(gè)屬性中的值對應(yīng)驶沼。每個(gè)值是浮點(diǎn)數(shù)且區(qū)間為[0,1],該屬性只在calculationMode屬性被設(shè)置為kCAAnimationLinear争群,kCAAnimaitonDiscrete,kCAAnimationCubic時(shí)被使用*/
@property(nullable, copy) NSArray<NSNumber *> *keyTimes;
/*CAMediaTimingFunction(CAAnimation類中有此屬性)數(shù)組大年,如果定義了n個(gè)關(guān)鍵幀换薄,則就有n-1個(gè)CAMediaTimingFunction對象,描述的是關(guān)鍵幀到幀的節(jié)奏(速度)(該屬性替換了繼承的**timingFunction**屬性)翔试。
*/
@property(nullable, copy) NSArray<CAMediaTimingFunction *> *timingFunctions;
/*
l calculationMode屬性定義了計(jì)算動畫定時(shí)的算法轻要。該屬性值會影響其他與定時(shí)相關(guān)屬性的使用方式。
l 線性和曲線動畫垦缅,設(shè)置為
kCAAnimationLinear:(默認(rèn)值,表示當(dāng)關(guān)鍵幀為座標(biāo)點(diǎn)的時(shí)候,關(guān)鍵幀之間直接直線相連進(jìn)行插值計(jì)算;)
CAAnimationCubic:(對關(guān)鍵幀為座標(biāo)點(diǎn)的關(guān)鍵幀進(jìn)行圓滑曲線相連后插值計(jì)算,對于曲線的形狀還可以通過tensionValues,continuityValues,biasValues來進(jìn)行調(diào)整,這里的主要目的是使得運(yùn)行的軌跡變得圓滑;)
冲泥,屬性值被用于提供定時(shí)器信息以生成動畫。這些模式值讓你最大化控制動畫的定時(shí)器壁涎。
l 節(jié)奏動畫凡恍,設(shè)置為
kCAAnimationPaced:(使得動畫均勻進(jìn)行,而不是按keyTimes設(shè)置的或者按關(guān)鍵幀平分時(shí)間,此時(shí)keyTimes和timingFunctions無效)
kCAAnimationCubicPaced:(在kCAAnimationCubic的基礎(chǔ)上使得動畫運(yùn)行變得均勻,就是系統(tǒng)時(shí)間內(nèi)運(yùn)動的距離相同,此時(shí)keyTimes以及timingFunctions也是無效的.)
這些屬性值不依賴由keyTimes或timingFunctions屬性提供的額外定時(shí)器值。相反怔球,定時(shí)器值被隱式地計(jì)算以提供一個(gè)常速率動畫嚼酝。
l 離散動畫,動畫的calculationMode屬性被設(shè)置為kCAAnimationDiscrete(離散的,就是不進(jìn)行插值計(jì)算,所有關(guān)鍵幀直接逐個(gè)進(jìn)行顯示;)竟坛,該值將引起動畫屬性從一個(gè)關(guān)鍵幀跳到另一個(gè)沒有任何補(bǔ)間動畫的下一個(gè)關(guān)鍵幀闽巩。計(jì)算模式使用keyTimes屬性值,但忽略**timingFunctions**屬性担汤。
*/
@property(copy) CAAnimationCalculationMode calculationMode;
// 動畫的張力涎跨,此屬性僅用于Cubic模式。正值表示較緊的曲線崭歧,而負(fù)值表示較圓的曲線隅很。第一個(gè)值定義了第一個(gè)控制點(diǎn)的切線的行為,第二個(gè)值控制了第二個(gè)點(diǎn)的切線率碾,依此類推外构。 如果未為給定的控制點(diǎn)指定值普泡,則使用值0。
@property(nullable, copy) NSArray<NSNumber *> *tensionValues;
/*
動畫的連續(xù)性值,此屬性僅用于Cubic模式审编。正值會導(dǎo)致尖銳的角撼班,而負(fù)值會導(dǎo)致倒角。 第一個(gè)值定義了第一個(gè)控制點(diǎn)的切線的行為垒酬,第二個(gè)值控制了第二個(gè)點(diǎn)的切線砰嘁,依此類推。 如果未為給定的控制點(diǎn)指定值勘究,則使用值0矮湘。
*/
@property(nullable, copy) NSArray<NSNumber *> *continuityValues;
/*
動畫的偏斜率,此屬性僅用于Cubic模式。 正值將曲線移到控制點(diǎn)之前口糕,而負(fù)值將曲線移到控制點(diǎn)之后缅阳。 第一個(gè)值定義了第一個(gè)控制點(diǎn)的切線的行為,第二個(gè)值控制了第二個(gè)點(diǎn)的切線景描,依此類推十办。 如果未為給定的控制點(diǎn)指定值,則使用值0超棺。
*/
@property(nullable, copy) NSArray<NSNumber *> *biasValues;
/*
設(shè)置path的動畫的對象是否旋轉(zhuǎn)以匹配路徑切線向族。它有兩個(gè)值kCAAnimationRotateAuto(自動旋轉(zhuǎn))kCAAnimationRotateAutoReverse(自動倒轉(zhuǎn))此屬性的默認(rèn)值為nil,它指示對象不應(yīng)旋轉(zhuǎn)以遵循路徑棠绘。
未提供path對象時(shí)件相,將此屬性設(shè)置為非nil值的效果是不確定的。
*/
@property(nullable, copy) CAAnimationRotationMode rotationMode;
CASpringAnimation 彈簧動畫
//質(zhì)量氧苍,影響圖層運(yùn)動時(shí)的彈簧慣性夜矗,質(zhì)量越大,彈簧拉伸和壓縮的幅度越大让虐。默認(rèn)為1侯养,且設(shè)置的時(shí)候必須大于0
@property CGFloat mass;
//剛度系數(shù)(勁度系數(shù)/彈性系數(shù)),剛度系數(shù)越大澄干,形變產(chǎn)生的力就越大逛揩,運(yùn)動越快。默認(rèn)為100麸俘,且設(shè)置的時(shí)候必須大于0
@property CGFloat stiffness;
//阻尼系數(shù)辩稽,阻止彈簧伸縮的系數(shù),阻尼系數(shù)越大从媚,停止越快逞泄,默認(rèn)為10,且設(shè)置的時(shí)候必須大于等于0
@property CGFloat damping;
//初始速率,動畫視圖的初始速度大小速率為正數(shù)時(shí)喷众,速度方向與運(yùn)動方向一致各谚,速率為負(fù)數(shù)時(shí),速度方向與運(yùn)動方向相反到千。默認(rèn)為0
@property CGFloat initialVelocity;
//結(jié)算時(shí)間昌渤,返回彈簧動畫到停止時(shí)的估算時(shí)間,根據(jù)當(dāng)前的動畫參數(shù)估算憔四,通常彈簧動畫的時(shí)間使用結(jié)算時(shí)間比較準(zhǔn)確
@property(readonly) CFTimeInterval settlingDuration;
CATransition
/*表示其漸變的效果的類型膀息。有4種分別為
kCATransitionFade(消退)kCATransitionMoveIn(漸入)kCATransitionPush(推動)kCATransitionReveal(揭開)等不同的效果
Defaults to `fade'. */
@property(copy) CATransitionType type;
//此類用于過渡運(yùn)動方向的轉(zhuǎn)變且分為上下左右四種:
//kCATransitionFromRight、kCATransitionFromLeft了赵、kCATransitionFromTop潜支、kCATransitionFromBottom
@property(nullable, copy) CATransitionSubtype subtype;
// 表示漸變開始的數(shù)值且其大小區(qū)間為[0,1],注意它必須小于或等于endProgress
// 例如,要在過渡進(jìn)行到一半時(shí)開始過渡柿汛,請將startProgress設(shè)置為0.5冗酿。
@property float startProgress;
//該值必須大于或等于startProgress,并且不大于1.0络断。 如果endProgress小于startProgress裁替,則行為未定義。 默認(rèn)值為1.0妓羊。
@property float endProgress;
CAAnimationGroup
@property(nullable, copy) NSArray<CAAnimation *> *animations;
同時(shí)進(jìn)行多個(gè)動畫。
如果你想同時(shí)給一個(gè)圖層對象應(yīng)用多個(gè)動畫稍计,你可以使用CAAnimationGroup對象將這些動畫放在一個(gè)組里躁绸。通過使用單獨(dú)的配置點(diǎn),使用組對象簡化了對多個(gè)動畫對象的管理臣嚣。應(yīng)用于動畫組的定時(shí)器和持續(xù)值將使用相同的值覆蓋單個(gè)動畫對象净刮。
CATransaction
對于分組動畫的更高級的方式是使用一個(gè)事務(wù)對象。事務(wù)提供了更加靈活的方式硅则,允許你創(chuàng)建內(nèi)嵌的動畫集合以及給每一個(gè)動畫賦值不同的動畫參數(shù)淹父。
對圖層屬性的每次更改都是事務(wù)的一部分。CATransaction類管理動畫的創(chuàng)建和分組并在適當(dāng)?shù)臅r(shí)間執(zhí)行動畫怎虫。在大部分情況下暑认,不需要?jiǎng)?chuàng)建事務(wù)。無論什么時(shí)候大审,給圖層添加顯式或隱式動畫蘸际,Core Animation會自動創(chuàng)建一個(gè)隱式事務(wù)。然而你也可以創(chuàng)建顯式事務(wù)以能夠更精確的管理動畫徒扶。
+ (void)begin; // 開始事務(wù)
+ (void)commit; // 提交事務(wù)
// 提交任何現(xiàn)存的隱式事務(wù)粮彤。
// 因?yàn)殡[式事務(wù)在runloop即將休眠時(shí)自動 flush 提交,如果沒有runloop,則此方法手動調(diào)用
//應(yīng)該避免顯式調(diào)用flush导坟。 通過runloop調(diào)用屿良,程序獲得更好的性能,原子性得保留惫周,并且事務(wù)之間進(jìn)行事務(wù)處理的事務(wù)和動畫將繼續(xù)起作用尘惧。
/*
使用場景
self.view.backgroundColor = [UIColor blueColor];
[CATransaction begin];
self.view.backgroundColor = [UIColor redColor];
[CATransaction commit];
[CATransaction flush]
while (YES) {} // 模擬耗時(shí)操作
*/
+ (void)flush;
/* 鎖定和解鎖全局鎖。該鎖是遞歸自旋鎖(即不應(yīng)長時(shí)間保持)闯两。*/
+ (void)lock;
+ (void)unlock;
/* 定義添加到圖層的動畫的默認(rèn)持續(xù)時(shí)間褥伴。 默認(rèn)為1 / 4s。*/
+ (CFTimeInterval)animationDuration;
+ (void)setAnimationDuration:(CFTimeInterval)dur;
/*
默認(rèn)值為nil漾狼,當(dāng)設(shè)置為非nil值時(shí)重慢,添加到圖層的所有動畫都將此值設(shè)置為其“ timingFunction”屬性。
*/
+ (nullable CAMediaTimingFunction *)animationTimingFunction;
+ (void)setAnimationTimingFunction:(nullable CAMediaTimingFunction *)function;
/*
定義是否使用圖層的-actionForKey:方法為每個(gè)圖層屬性更改查找動作(也稱為隱式動畫)逊躁。 默認(rèn)為否似踱,即啟用了隱式動畫。
*/
+ (BOOL)disableActions;
+ (void)setDisableActions:(BOOL)flag;
/*
一旦設(shè)置為非nil值稽煤,就保證此事務(wù)組隨后添加的所有動畫都已完成(或被刪除)核芽,就立即調(diào)用該塊(在主線程上)。 如果在提交當(dāng)前CATransaction之前未添加任何動畫(或?qū)⑼瓿蓧K設(shè)置為其他值)酵熙,則將立即調(diào)用該塊轧简。
*/
+ (nullable void (^)(void))completionBlock;
+ (void)setCompletionBlock:(nullable void (^)(void))block;
#endif
/*
將任意鍵控?cái)?shù)據(jù)與當(dāng)前事務(wù)關(guān)聯(lián)(即與當(dāng)前線程關(guān)聯(lián))
讀取鍵會搜索已設(shè)置它的最內(nèi)作用域,設(shè)置鍵始終會將它設(shè)置在最內(nèi)作用域匾二。
當(dāng)前支持的事務(wù)屬性包括:“ animationDuration”哮独,“ animationTimingFunction”,“ completionBlock”察藐,“ disableActions”皮璧。
*/
+ (nullable id)valueForKey:(NSString *)key;
+ (void)setValue:(nullable id)anObject forKey:(NSString *)key;
在你想提供不同默認(rèn)值給不同的動畫集合的情況下你可以內(nèi)嵌事務(wù)。但是嵌套在內(nèi)層的事務(wù)不會立即commit分飞,會在最外層的事務(wù)結(jié)束后統(tǒng)一commit悴务。
動畫的停止
動畫通常直到運(yùn)行結(jié)束才會停止,但是你也可以根據(jù)需要提前停止動畫:
- 調(diào)用圖層的removeAnimationForKey:方法移除你的動畫對象譬猫。該方法使用的鍵要與調(diào)用addAnimation:forKey:方法傳入的鍵一致讯檐。你指定的鍵必須不為nil。
- 調(diào)用圖層的removeAllAnimations方法染服。會立即移除所有進(jìn)行中的動畫裂垦,并使用圖層當(dāng)前的狀態(tài)信息重繪圖層。
檢測一個(gè)動畫的結(jié)束
Core Animaiton提供對動畫開始與結(jié)束的檢測支持肌索。這些通知是執(zhí)行所有與動畫相關(guān)的內(nèi)務(wù)處理的最佳時(shí)刻蕉拢。比如說你可能使用開始通知設(shè)置一些相關(guān)狀態(tài)信息特碳,使用對應(yīng)的結(jié)束通知清理這些狀態(tài)。
有兩種不同的方式獲取關(guān)于動畫狀態(tài)的通知:
使用setCompletionBlock:方法添加一個(gè)完成塊給當(dāng)前的事務(wù)晕换。當(dāng)事務(wù)中的所有動畫完成后午乓,事務(wù)將執(zhí)行你的完成塊。
給CAAnimaiton對象賦值一個(gè)代理闸准,該代理實(shí)現(xiàn)了animationDidStart:方法和animaitonDidStop:finished:代理方法益愈。
如果想將兩個(gè)動畫鏈接在一起,當(dāng)?shù)谝粋€(gè)動畫結(jié)束之后啟動第二個(gè)動畫夷家。不要使用動畫通知蒸其。
使用動畫對象的beginTime屬性在某個(gè)時(shí)間啟動動畫。設(shè)置第二個(gè)動畫的開始時(shí)間為第一個(gè)動畫的結(jié)束時(shí)間库快。
UIView動畫
因?yàn)閕OS UIView總有一個(gè)Layer摸袁,UIView類從Layer對象派生了大部分的數(shù)據(jù)。因此义屏,對layer屬性的更改會通過view對象表現(xiàn)出來靠汁。因此也可以使用UIVIew接口完成對圖層屬性的更改。
如果想使用Core Animation初始化動畫闽铐,你必須在一個(gè)基于視圖的動畫塊內(nèi)部執(zhí)行所有Core Animaiton調(diào)用蝶怔。
UIView類默認(rèn)是關(guān)閉圖層動畫的,在動畫塊之外所做的改變都不是動畫兄墅,但是你可在動畫塊中重新啟用圖層動畫踢星。下面的代碼,兩個(gè)動畫都開始于相同的時(shí)間隙咸,但透明度動畫使用默認(rèn)的定時(shí)沐悦,而位置動畫使用動畫對象指定的定時(shí)。
[UIView animateWithDuration:1.0 animations:^{
myView.layer.opacity = 0.0;
CABasicAnimation* theAnim=[CABasicAnimation animationWithKeyPath:@"position"];
theAnim.fromValue = [NSValue valueWithCGPoint:myView.layer.position];
theAnim.toValue = [NSValue valueWithCGPoint:myNewPosition];
theAnim.duration = 3.0;
[myView.layer addAnimation:theAnim forKey:@"AnimateFrame"];
}];
動畫的定時(shí)
時(shí)間系統(tǒng)是動畫的一個(gè)重要部分扎瓶。通過Core Animation方法和CAMediaTiming協(xié)議可為動畫指定精確的時(shí)間信息所踊。共有兩個(gè)Core Animation類適配該協(xié)議泌枪。
其一是CAAnimation類概荷,所以你可以在動畫對象中指定時(shí)間信息。
其二是CALayer碌燕,你可以為隱式動畫配置一些與時(shí)間相關(guān)的功能误证。雖然隱式事務(wù)對象包裝了這些動畫,通常優(yōu)先使用所提供的默認(rèn)時(shí)間信息修壕。
當(dāng)考慮時(shí)間與動畫的時(shí)候愈捅,理解圖層對象如何與時(shí)間工作是重要的。每一個(gè)圖層都有自己用于管理動畫定時(shí)的本地時(shí)間系統(tǒng)慈鸠。
一般兩個(gè)不同圖層的本地時(shí)間系統(tǒng)足夠的接近蓝谨,也可以為每一個(gè)圖層指定相同的時(shí)間值。
圖層的本地時(shí)間可以被父圖層或自己的定時(shí)參數(shù)更改。比如說譬巫,改變圖層的speed屬性將引起圖層或子圖層上動畫的持續(xù)時(shí)間成比例的變化咖楣。
為了確定一個(gè)圖層的適當(dāng)時(shí)間值,CALayer類定義了convertTime:fromLayer:
以及convertTime:toLayer:
方法芦昔。你可以使用這些方法轉(zhuǎn)化一個(gè)固定的時(shí)間值到一個(gè)圖層的本地時(shí)間系統(tǒng)诱贿,或者將某一圖層的時(shí)間值轉(zhuǎn)換為另一個(gè)圖層的時(shí)間值。
// CACurrentMediaTime函數(shù)是一個(gè)便利函數(shù)咕缎,返回計(jì)算機(jī)的當(dāng)前時(shí)鐘時(shí)間珠十,該方法用于獲取并轉(zhuǎn)換至圖層的本地時(shí)間。
CFTimeInterval localLayerTime = [myLayer convertTime:CACurrentMediaTime() fromLayer:nil];
一旦圖層的本地時(shí)間系統(tǒng)中有一個(gè)時(shí)間值凭豪,可以使用該值更新與事件相關(guān)的動畫對象或圖層的屬性焙蹭。使用這些定時(shí)屬性,可以完成一些有趣的動畫行為墅诡,包括:
使用beginTime屬性設(shè)置動畫的開始時(shí)間壳嚎。通常,動畫開始于下一個(gè)更新循環(huán)周期末早。你可以使用beginTime參數(shù)延遲動畫的開始幾秒鐘時(shí)間烟馅。該方式將鏈接在一起的兩個(gè)動畫設(shè)置某一個(gè)動畫的開始時(shí)間為另一個(gè)動畫的結(jié)束時(shí)間。
autoreverses屬性引起一個(gè)動畫在指定的持續(xù)時(shí)間內(nèi)執(zhí)行并返回到動畫的開始值然磷。你可以將此屬性與repeatCount屬性聯(lián)合使用郑趁,讓動畫在開始與結(jié)束值之間反復(fù)來回。對自動返回動畫設(shè)置重復(fù)計(jì)數(shù)為一個(gè)整數(shù)(比如1.0)將引起動畫停止在動畫的開始值姿搜。添加一個(gè)半拍值(比如重復(fù)計(jì)數(shù)為1.5)將引起動畫停止在它的結(jié)束值寡润。
對動畫組中的動畫使用timeOffset屬性,讓動畫一開始就出現(xiàn)在以后某時(shí)刻才會出現(xiàn)的狀態(tài)舅柜。(一個(gè)持續(xù)時(shí)間為5秒的動畫梭纹。動畫將從時(shí)間0到時(shí)間5運(yùn)行。如果將timeOffset設(shè)置為2,則動畫將在時(shí)間2開始烫扼,到達(dá)時(shí)間5蜻底,然后“環(huán)繞”并在時(shí)間0到時(shí)間2運(yùn)行。)
暫停與恢復(fù)動畫
為了暫停一個(gè)動畫绍载,可以利用CAMediaTiming協(xié)議,設(shè)置圖層動畫的速度為0.0.設(shè)置速度為0暫停動畫直到你改變該屬性值為一個(gè)非零值滔蝉,
-(void)pauseLayer:(CALayer*)layer {
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime()
fromLayer:nil];
layer.speed = 0.0;
layer.timeOffset = pausedTime;
}
-(void)resumeLayer:(CALayer*)layer {
CFTimeInterval pausedTime = [layer timeOffset];
layer.speed = 1.0;
layer.timeOffset = 0.0;
layer.beginTime = 0.0;
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime()
fromLayer:nil] - pausedTime;
layer.beginTime = timeSincePause;
}
改變一個(gè)圖層的默認(rèn)隱式動畫
Core Animation使用動作對象為圖層實(shí)現(xiàn)了隱式動畫行為击儡。動作對象遵守CAAction協(xié)議并定義了一些運(yùn)行于圖層的相關(guān)行為。
所有CAAnimation對象都實(shí)現(xiàn)了這個(gè)協(xié)議蝠引。
自定義動作對象
為了創(chuàng)建你自己的動作對象阳谍,你需要遵守CAAction協(xié)議并實(shí)現(xiàn)協(xié)議里唯一的方法:runActionForKey:object:arguments:
方法蛀柴。在該方法中執(zhí)行在圖層上的動作。你可能使用該方法給圖層添加動畫對象或使用該方法執(zhí)行另外的任務(wù)矫夯。
當(dāng)定義了一個(gè)動作對象名扛,必須決定動作以何種方式被觸發(fā)。動作的觸發(fā)器定義了你用于注冊動作的key茧痒。動作對象可在下面的情況下被觸發(fā):
圖層的某一個(gè)屬性值被改變肮韧。這可以是圖層的任何一個(gè)屬性,不僅僅是可動畫的屬性旺订。 (你也可以給添加到圖層的自定義屬性關(guān)聯(lián)動作弄企。)識別動作的鍵是屬性名。
圖層變成可視或被加入到圖層層次中区拳。則識別動作的鍵為kCAOnOrderIn拘领。
圖層從圖層層次中被移除。則識別動作的鍵為kCAOnOrderOut樱调。
圖層是即將包含一個(gè)變換動畫约素。則識別動作的鍵為kCATransition。
@interface CustomAction : NSObject<CAAction>
@property (nonatomic) CGColorRef currentColor;
@end
@implementation CustomAction
- (void)runActionForKey:(NSString *)key object:(id)anObject arguments:(NSDictionary *)dict {
CustomLayer *layer = anObject;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
animation.fromValue = (id)[UIColor greenColor].CGColor;
animation.toValue = (id)[UIColor redColor].CGColor;
animation.duration = 5;
[layer addAnimation:animation forKey:@"backgroundColor"];
}
@end
動作對象設(shè)置給圖層才產(chǎn)生效果
在動作被執(zhí)行之前笆凌,圖層需要找到相應(yīng)的動作對象圣猎。相關(guān)的動作的鍵可以是被更改的屬性名或一個(gè)特殊的識別動作的字符串。
當(dāng)事件發(fā)生在圖層上乞而,圖層調(diào)用它的actionForKey:方法搜索與鍵關(guān)聯(lián)的動作對象送悔。我們可以介入,并提供一個(gè)與鍵相關(guān)的動作對象爪模。
Core Animation以下面的順序搜索動作對象:
- 如果圖層有一個(gè)代理欠啤,并且代理實(shí)現(xiàn)了actionForLayer:forKey:方法,圖層調(diào)用該方法屋灌。代理必須完成下面所述操作之一:
l 返回給定的鍵指定的動作對象
l 如果代理不處理動作則返回nil洁段,而搜索操作將繼續(xù)。
l 返回NSNull對象共郭,這將引起搜索操作立即結(jié)束祠丝。CALayer不會做任何動畫; - 圖層在圖層的action字典內(nèi)搜索給定的鍵
- 圖層在style字典中查詢一個(gè)包含鍵的動作字典落塑。(換句話說纽疟,style字典包含一個(gè)actions鍵罐韩,它的值也是字典憾赁。圖層在第二個(gè)字典中搜索給定的鍵。)
- 圖層調(diào)用它的defaultActionForKey:類方法散吵。 圖層執(zhí)行由Core Animation定義的隱式動作(如果有)龙考。
如果任何一個(gè)搜索點(diǎn)提供了動作對象蟆肆,圖層將停止搜索并執(zhí)行返回對象的runActionForKey:object:arguments:
方法執(zhí)行動作。
如果動作是一個(gè)CAAnimation對象晦款,則把自身添加到layer上炎功,使用默認(rèn)的方法實(shí)現(xiàn)執(zhí)行動畫。如果是一個(gè)正確的實(shí)現(xiàn)了CAAction協(xié)議的對象缓溅,則CALayer用這個(gè)對象來生成一個(gè)CAAnimation蛇损,并加到自己身上進(jìn)行動畫。
CAAnimation
CALayer可動畫屬性
屬性 | 默認(rèn)動畫 |
---|---|
anchorPoint | 使用默認(rèn)隱式的CABasicAnimation對象坛怪,描述于Table B-2淤齐。 |
backgroundColor | 使用默認(rèn)的隱式CABasicAnimation對象,描述于Table B-2袜匿。 |
backgroundFilters | 使用默認(rèn)的CATransition對象更啄,描述于Table B-3。濾鏡的字屬性被動畫使用默認(rèn)隱式CABasicAnimation對象居灯,描述于Table B-2祭务。 |
borderColor | 使用默認(rèn)隱式的CABasicAnimation對象,描述于Table B-2怪嫌。 |
borderWidth | 使用默認(rèn)隱式的CABasicAnimation對象义锥,描述于Table B-2。 |
bounds | 使用默認(rèn)隱式的CABasicAnimation對象岩灭,描述于Table B-2缨该。 |
compositingFilter | 使用默認(rèn)的CATransition對象,描述于Table B-3川背。濾鏡的字屬性被動畫使用默認(rèn)隱式CABasicAnimation對象贰拿,描述于Table B-2。 |
contents | 使用默認(rèn)隱式的CABasicAnimation對象熄云,描述于Table B-2)膨更。 |
contentsRect | 使用默認(rèn)隱式的CABasicAnimation對象,描述于Table B-2缴允。 |
cornerRadius | 使用默認(rèn)隱式的CABasicAnimation對象荚守,描述于Table B-2。 |
doubleSided | 沒有默認(rèn)的隱式動畫 |
filters | 使用默認(rèn)的CATransition對象练般,描述于Table B-3矗漾。濾鏡的字屬性被動畫使用默認(rèn)隱式CABasicAnimation對象,描述于Table B-2薄料。 |
frame | 該屬性是不可動畫的敞贡。你可以動畫bounds和position屬性達(dá)到相同的效果。 |
hidden | 使用默認(rèn)隱式的CABasicAnimation對象摄职,描述于Table B-2誊役。 |
mask | 使用默認(rèn)隱式的CABasicAnimation對象获列,描述于Table B-2。 |
masksToBounds | 使用默認(rèn)隱式的CABasicAnimation對象蛔垢,描述于Table B-2击孩。 |
opacity | 使用默認(rèn)隱式的CABasicAnimation對象,描述于Table B-2鹏漆。 |
position | 使用默認(rèn)隱式的CABasicAnimation對象巩梢,描述于Table B-2。 |
shadowColor | 使用默認(rèn)隱式的CABasicAnimation對象艺玲,描述于Table B-2且改。 |
shadowOffset | 使用默認(rèn)隱式的CABasicAnimation對象,描述于Table B-2板驳。 |
shadowOpacity | 使用默認(rèn)隱式的CABasicAnimation對象又跛,描述于Table B-2。 |
shadowPath | 使用默認(rèn)隱式的CABasicAnimation對象若治,描述于Table B-2慨蓝。 |
shadowRadius | 使用默認(rèn)隱式的CABasicAnimation對象,描述于Table B-2端幼。 |
sublayers | 使用默認(rèn)隱式的CABasicAnimation對象礼烈,描述于Table B-2。 |
sublayerTransform | 使用默認(rèn)隱式的CABasicAnimation對象婆跑,描述于Table B-2此熬。 |
transform | 使用默認(rèn)隱式的CABasicAnimation對象,描述于Table B-2滑进。 |
zPosition | 使用默認(rèn)隱式的CABasicAnimation對象犀忱,描述于Table B-2。 |
表B-2 默認(rèn)隱式的基本動畫
描述 | 值 |
---|---|
類 | CABasicAnimation |
持續(xù)時(shí)間 | 0.25秒扶关,或是當(dāng)前事務(wù)的持續(xù)時(shí)間 |
鍵路徑 | 設(shè)置圖層的屬性名 |
表B-3 默認(rèn)隱式過渡
描述 | 值 |
---|---|
類 | CATransition |
持續(xù)時(shí)間 | 0.25秒阴汇,或當(dāng)前事務(wù)的持續(xù)時(shí)間 |
類型 | 減淡(kCATransitionFade) |
開始進(jìn)度 | 0.0 |
結(jié)束進(jìn)度 | 1.0 |
CATransform3D鍵路徑
可以使用鍵路徑檢索一個(gè)CATransform3D數(shù)據(jù)類型的屬性的變換值〗诨保可使用字符串值transform或sublayerTransform搀庶,后面跟上表C-2中中的域作為鍵路徑。比如铜异,transform.rotation.z哥倔。
表C-2 變換域的鍵路徑
域的鍵路徑 | 描述 |
---|---|
rotation.x | 設(shè)置一個(gè)NSNumber類型的繞x方向旋轉(zhuǎn)的弧度值。 |
rotation.y | 設(shè)置一個(gè)NSNumber類型的繞y方向旋轉(zhuǎn)的弧度值揍庄。 |
rotation.z | 設(shè)置一個(gè)NSNumber類型的繞z方向旋轉(zhuǎn)的弧度值咆蒿。 |
rotation | 設(shè)置一個(gè)NSNumber類型的繞z方向旋轉(zhuǎn)的弧度值。該設(shè)置和ratation.z是功能是一樣的。 |
scale.x | 設(shè)置一個(gè)NSNumber對象蜡秽,它的值是在x軸上縮放因子。 |
scale.y | 設(shè)置一個(gè)NSNumber對象缆镣,它的值是在y軸上縮放因子芽突。 |
scale.z | 設(shè)置一個(gè)NSNumber對象,它的值是在z軸上縮放因子董瞻。 |
scale | 設(shè)置一個(gè)NSNumber對象寞蚌,它的值是三個(gè)縮放因子的平均值。 |
translation.x | 設(shè)置一個(gè)NSNumber對象钠糊,它的值是x軸方向的平移因子挟秤。 |
translation.y | 設(shè)置一個(gè)NSNumber對象,它的值是y軸方向的平移因子抄伍。 |
translation.z | 設(shè)置一個(gè)NSNumber對象艘刚,它的值是z軸方向的平移因子。 |
translation | 設(shè)置一個(gè)包含NSSize或CGSize數(shù)據(jù)類型的NSValue對象截珍。該數(shù)據(jù)類型表明在x和y軸上的平移數(shù)量攀甚。 |
//設(shè)置x軸的平移因子為10點(diǎn),圖層將按指定的坐標(biāo)軸方向平移給定的點(diǎn)數(shù)量岗喉。
[myLayer setValue:[NSNumber numberWithFloat:10.0] forKeyPath:@”transform.translation.x”];
CGPoint鍵路徑
如果屬性的值是CGPoint數(shù)據(jù)類型秋度,你可以選擇表C-3其中的域名追加給屬性以獲得值或設(shè)置值 。
表C-3 CGPoint數(shù)據(jù)結(jié)構(gòu)
結(jié)構(gòu)域 | 描述 |
---|---|
x | 一個(gè)點(diǎn)的x坐標(biāo)钱床。 |
y | 一個(gè)點(diǎn)的y坐標(biāo)荚斯。 |
CGSize鍵路徑
如果屬性值是一個(gè)CGSize數(shù)據(jù)類型,你可以選擇表C-4中其中一個(gè)域名追加給屬性以獲得值或設(shè)置值查牌。
表C-4 CGSize數(shù)據(jù)結(jié)構(gòu)域
結(jié)構(gòu)域 | 描述 |
---|---|
width | size的width屬性事期。 |
height | size的height屬性。 |
CGRect鍵路徑
如果給定的屬性是CGRect數(shù)據(jù)類型值纸颜,你可以選擇表C-5中其中一個(gè)域名追加給屬性以獲取或設(shè)置值刑赶。
表C-5 CGRect數(shù)據(jù)結(jié)構(gòu)的域名
結(jié)構(gòu)體域 | 描述 |
---|---|
orign | 矩形的原始點(diǎn) |
origin.x | 矩形原始點(diǎn)的x坐標(biāo) |
origin.y | 矩形原始點(diǎn)的y坐標(biāo) |
size | 矩形的尺寸 |
size.width | 矩形尺寸的寬度屬性 |
size.height | 矩形尺寸的高度屬性 |
UIView動畫
UIView動畫是iOS開發(fā)中最廉價(jià)也是最常用的動畫。
UIView動畫能夠設(shè)置的動畫屬性有:
- frame
- bounds
- center
- transform
- alpha
- backgroundColor
- contentStretch
UIView動畫使用方式
類似于事務(wù)的方式(在iOS13 廢棄了)
創(chuàng)建動畫
// 第一個(gè)參數(shù): 動畫標(biāo)識
// 第二個(gè)參數(shù): 附加參數(shù),在設(shè)置代理情況下懂衩,
//此參數(shù)將發(fā)送到setAnimationWillStartSelector和setAnimationDidStopSelector所指定的方法撞叨,
//大部分情況,設(shè)置為nil.
[UIView beginAnimations:(nullable NSString *) context:(nullable void *)];
提交動畫
[UIView commitAnimations];
相關(guān)方法
//動畫持續(xù)時(shí)間
[UIView setAnimationDuration:(NSTimeInterval)];
//動畫的代理對象
[UIView setAnimationDelegate:(nullable id)];
//設(shè)置動畫將開始時(shí)代理對象執(zhí)行的SEL
[UIView setAnimationWillStartSelector:(nullable SEL)];
//設(shè)置動畫延遲執(zhí)行的時(shí)間
[UIView setAnimationDelay:(NSTimeInterval)];
//設(shè)置動畫的重復(fù)次數(shù)
[UIView setAnimationRepeatCount:(float)];
//設(shè)置動畫的曲線
/*
UIViewAnimationCurve的枚舉值:
UIViewAnimationCurveEaseInOut, // 慢進(jìn)慢出(默認(rèn)值)
UIViewAnimationCurveEaseIn, // 慢進(jìn)
UIViewAnimationCurveEaseOut, // 慢出
UIViewAnimationCurveLinear // 勻速
*/
[UIView setAnimationCurve:(UIViewAnimationCurve)];
//設(shè)置是否從當(dāng)前狀態(tài)開始播放動畫
/*假設(shè)上一個(gè)動畫正在播放浊洞,且尚未播放完畢牵敷,我們將要進(jìn)行一個(gè)新的動畫:
當(dāng)為YES時(shí):動畫將從上一個(gè)動畫所在的狀態(tài)開始播放
當(dāng)為NO時(shí):動畫將從上一個(gè)動畫所指定的最終狀態(tài)開始播放(此時(shí)上一個(gè)動畫馬上結(jié)束)*/
[UIView setAnimationBeginsFromCurrentState:YES];
//設(shè)置動畫是否繼續(xù)執(zhí)行相反的動畫
[UIView setAnimationRepeatAutoreverses:(BOOL)];
//是否禁用動畫效果(對象屬性依然會被改變,只是沒有動畫效果)
[UIView setAnimationsEnabled:(BOOL)];
//設(shè)置視圖的過渡效果
/* 第一個(gè)參數(shù):UIViewAnimationTransition的枚舉值如下
UIViewAnimationTransitionNone, //不使用動畫
UIViewAnimationTransitionFlipFromLeft, //從左向右旋轉(zhuǎn)翻頁
UIViewAnimationTransitionFlipFromRight, //從右向左旋轉(zhuǎn)翻頁
UIViewAnimationTransitionCurlUp, //從下往上卷曲翻頁
UIViewAnimationTransitionCurlDown, //從上往下卷曲翻頁
第二個(gè)參數(shù):需要過渡效果的View
第三個(gè)參數(shù):是否使用視圖緩存法希,YES:視圖在開始和結(jié)束時(shí)渲染一次枷餐;NO:視圖在每一幀都渲染*/
[UIView setAnimationTransition:(UIViewAnimationTransition) forView:(nonnull UIView *) cache:(BOOL)];
Block 動畫
@interface UIView(UIViewAnimation)
// 動畫是否可用
+ (void)setAnimationsEnabled:(BOOL)enabled;
@property(class, nonatomic, readonly) BOOL areAnimationsEnabled;
// 在沒有動畫的情況下執(zhí)行block里的代碼。
+ (void)performWithoutAnimation:(void (NS_NOESCAPE ^)(void))actionsWithoutAnimation API_AVAILABLE(ios(7.0));
//當(dāng)前動畫的持續(xù)時(shí)間苫亦。?
@property(class, nonatomic, readonly) NSTimeInterval inheritedAnimationDuration API_AVAILABLE(ios(9.0));
@end
@interface UIView(UIViewAnimationWithBlocks)
/*
UIViewAnimationOptionLayoutSubviews //進(jìn)行動畫時(shí)布局子控件
UIViewAnimationOptionAllowUserInteraction //進(jìn)行動畫時(shí)允許用戶交互
UIViewAnimationOptionBeginFromCurrentState //從當(dāng)前狀態(tài)開始動畫
UIViewAnimationOptionRepeat //無限重復(fù)執(zhí)行動畫
UIViewAnimationOptionAutoreverse //執(zhí)行動畫回路
UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套動畫的執(zhí)行時(shí)間設(shè)置
UIViewAnimationOptionOverrideInheritedCurve //忽略嵌套動畫的曲線設(shè)置
UIViewAnimationOptionAllowAnimatedContent //轉(zhuǎn)場:進(jìn)行動畫時(shí)重繪視圖
UIViewAnimationOptionShowHideTransitionViews //轉(zhuǎn)場:移除(添加和移除圖層的)動畫效果
UIViewAnimationOptionOverrideInheritedOptions //不繼承父動畫設(shè)置
UIViewAnimationOptionCurveEaseInOut //時(shí)間曲線毛肋,慢進(jìn)慢出(默認(rèn)值)
UIViewAnimationOptionCurveEaseIn //時(shí)間曲線怨咪,慢進(jìn)
UIViewAnimationOptionCurveEaseOut //時(shí)間曲線,慢出
UIViewAnimationOptionCurveLinear //時(shí)間曲線润匙,勻速
UIViewAnimationOptionTransitionNone //轉(zhuǎn)場诗眨,不使用動畫
UIViewAnimationOptionTransitionFlipFromLeft //轉(zhuǎn)場,從左向右旋轉(zhuǎn)翻頁
UIViewAnimationOptionTransitionFlipFromRight //轉(zhuǎn)場孕讳,從右向左旋轉(zhuǎn)翻頁
UIViewAnimationOptionTransitionCurlUp //轉(zhuǎn)場匠楚,下往上卷曲翻頁
UIViewAnimationOptionTransitionCurlDown //轉(zhuǎn)場,從上往下卷曲翻頁
UIViewAnimationOptionTransitionCrossDissolve //轉(zhuǎn)場厂财,交叉消失和出現(xiàn)
UIViewAnimationOptionTransitionFlipFromTop //轉(zhuǎn)場芋簿,從上向下旋轉(zhuǎn)翻頁
UIViewAnimationOptionTransitionFlipFromBottom //轉(zhuǎn)場,從下向上旋轉(zhuǎn)翻頁
*/
// 可以設(shè)置延時(shí)時(shí)間和過渡效果的Block動畫
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion API_AVAILABLE(ios(4.0));
// 帶有動畫提交回調(diào)的Block動畫
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion API_AVAILABLE(ios(4.0)); // delay = 0.0, options = 0
// 最簡潔的Block動畫:包含時(shí)間和動畫:
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations API_AVAILABLE(ios(4.0)); // delay = 0.0, options = 0, completion = NULL
// 彈簧動畫
// 參數(shù)依次是
//動畫持續(xù)時(shí)間
//動畫延遲執(zhí)行的時(shí)間
//震動效果璃饱,范圍0~1与斤,數(shù)值越小震動效果越明顯
//初始速度,數(shù)值越大初始速度越快
//動畫的過渡效果
//執(zhí)行的動畫
//動畫執(zhí)行提交后的操作
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion API_AVAILABLE(ios(7.0));
// 轉(zhuǎn)場動畫
// 單個(gè)視圖的過渡效果
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))animations completion:(void (^ __nullable)(BOOL finished))completion API_AVAILABLE(ios(4.0));
/*
toView已添加到fromView.superview荚恶,fromView已從其超級視圖中刪除注意轉(zhuǎn)場動畫的作用對象是父視圖(過渡效果體現(xiàn)在父視圖上)幽告。調(diào)用該方法相當(dāng)于執(zhí)行下面兩句代碼:
[fromView.superview addSubview:toView];
[fromView removeFromSuperview];
*/
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^ __nullable)(BOOL finished))completion API_AVAILABLE(ios(4.0));
/* 在一個(gè)或多個(gè)視圖上執(zhí)行請求的系統(tǒng)提供的動畫。 在parallelAnimations塊中指定其他動畫裆甩。 這些附加動畫將與系統(tǒng)動畫一起運(yùn)行冗锁,并具有與系統(tǒng)動畫定義/繼承相同的時(shí)間和持續(xù)時(shí)間。 其他動畫不應(yīng)修改在其上執(zhí)行系統(tǒng)動畫的視圖的屬性嗤栓。 并非所有的系統(tǒng)動畫支持所有的options冻河。
*/
+ (void)performSystemAnimation:(UISystemAnimation)animation onViews:(NSArray<__kindof UIView *> *)views options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))parallelAnimations completion:(void (^ __nullable)(BOOL finished))completion API_AVAILABLE(ios(7.0));
/*
從動畫塊中調(diào)用此方法以重復(fù)動畫,否則無效茉帅。 重復(fù)動畫的總持續(xù)時(shí)間可以通過(outerAnimationDuration * repeatCount * autoreverses叨叙?2:1)計(jì)算。
*/
+ (void)modifyAnimationsWithRepeatCount:(CGFloat)count autoreverses:(BOOL)autoreverses animations:(void(NS_NOESCAPE ^)(void))animations API_AVAILABLE(ios(12.0),tvos(12.0));
@end
@interface UIView (UIViewKeyframeAnimations)
/*
UIViewAnimationOptionLayoutSubviews //進(jìn)行動畫時(shí)布局子控件
UIViewAnimationOptionAllowUserInteraction //進(jìn)行動畫時(shí)允許用戶交互
UIViewAnimationOptionBeginFromCurrentState //從當(dāng)前狀態(tài)開始動畫
UIViewAnimationOptionRepeat //無限重復(fù)執(zhí)行動畫
UIViewAnimationOptionAutoreverse //執(zhí)行動畫回路
UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套動畫的執(zhí)行時(shí)間設(shè)置
UIViewAnimationOptionOverrideInheritedOptions //不繼承父動畫設(shè)置
UIViewKeyframeAnimationOptionCalculationModeLinear //運(yùn)算模式 :連續(xù)
UIViewKeyframeAnimationOptionCalculationModeDiscrete //運(yùn)算模式 :離散
UIViewKeyframeAnimationOptionCalculationModePaced //運(yùn)算模式 :均勻執(zhí)行
UIViewKeyframeAnimationOptionCalculationModeCubic //運(yùn)算模式 :平滑
UIViewKeyframeAnimationOptionCalculationModeCubicPaced //運(yùn)算模式 :平滑均勻
*/
// 關(guān)鍵幀動畫堪澎,支持屬性關(guān)鍵幀擂错,不支持路徑關(guān)鍵幀
+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion API_AVAILABLE(ios(7.0));
//動畫開始的時(shí)間(占總時(shí)間的比例),
// 動畫持續(xù)時(shí)間(占總時(shí)間的比例)
+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations API_AVAILABLE(ios(7.0)); // start time and duration are values between 0.0 and 1.0 specifying time and duration relative to the overall time of the keyframe animation
@end
UIView 動畫原理
之前已經(jīng)介紹過,隱式動畫的執(zhí)行過程樱蛤,是通過找到一個(gè) 實(shí)現(xiàn)了 CAAction
協(xié)議的類對象钮呀,調(diào)用協(xié)議方法實(shí)現(xiàn)的。
當(dāng)直接修改View的屬性昨凡,也會反饋到layer上爽醋,但并沒有動畫,是因?yàn)楸慵梗瑅iew是layer的代理蚂四,返回了NSNull對象,不會產(chǎn)生動畫
當(dāng)使用UIView提供的api進(jìn)行動畫時(shí),會返回一個(gè)Action對象遂赠,然后該對象添加了動畫久妆。
/** UIView 動畫產(chǎn)生原理 */
- (void)uiviewAnimation {
NSLog(@"%@",[self.view.layer.delegate actionForLayer:self.view.layer forKey:@"position"]); // <null>
[UIView animateWithDuration:1.25 animations:^{
NSLog(@"%@",[self.view.layer.delegate actionForLayer:self.view.layer forKey:@"position"]); // <_UIViewAdditiveAnimationAction: 0x600001ff0d40>
}];
}
UIViewController轉(zhuǎn)場動畫
簡單描述下UIViewController轉(zhuǎn)場動畫
自定義轉(zhuǎn)場動畫
在 Navigation Controller 中,實(shí)現(xiàn)一個(gè)自定義的 push 動畫效果跷睦。為了完成這個(gè)任務(wù)筷弦,需要實(shí)現(xiàn) UINavigationControllerDelegate
中的方法:
//可以根據(jù)不同的 operation(Push 或 Pop)返回不同的 animator。我們可以把 animator 存到一個(gè)屬性中送讲,從而在多個(gè) operation 之間實(shí)現(xiàn)共享奸笤,或者我們也可以為每個(gè) operation 都創(chuàng)建一個(gè)新的 animator 對象
- (id<UIViewControllerAnimatedTransitioning>)
navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController*)fromVC
toViewController:(UIViewController*)toVC
{
if (operation == UINavigationControllerOperationPush) {
return self.animator;
}
return nil;
}
我們需要?jiǎng)?chuàng)建遵守UIViewControllerAnimatedTransitioning
協(xié)議的對象惋啃。
@protocol UIViewControllerAnimatedTransitioning <NSObject>
//詢問動畫對象過渡動畫的持續(xù)時(shí)間(以秒為單位)哼鬓。
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext;
/*
在呈現(xiàn)或關(guān)閉視圖控制器時(shí),會調(diào)用此方法边灭∫煜#可以配置與自定義過渡相關(guān)聯(lián)的動畫。您可以使用UIView動畫或“核心動畫”來配置動畫绒瘦。
所有動畫都必須在transitionContext的containerView屬性指定的視圖中進(jìn)行称簿。
將要顯示的視圖添加到容器視圖的層次結(jié)構(gòu)中,并設(shè)置您想要使該視圖移動到位的所有動畫惰帽。
如果要在沒有視圖的情況下直接繪制到屏幕憨降,請使用此方法配置CADisplayLink對象。
您可以從transitionContext的viewControllerForKey:方法檢索與轉(zhuǎn)換有關(guān)的視圖控制器该酗。
*/
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;
@optional
//如果轉(zhuǎn)場可以被中斷授药,則實(shí)現(xiàn)此方法(例如UIViewPropertyAnimator對象)
- (id <UIViewImplicitlyAnimating>) interruptibleAnimatorForTransition:(id <UIViewControllerContextTransitioning>)transitionContext API_AVAILABLE(ios(10.0));
// 這是一種便利,如果在調(diào)用過渡上下文的completeTransition:方法時(shí)實(shí)現(xiàn)呜魄,則將由系統(tǒng)調(diào)用該實(shí)現(xiàn)悔叽。
- (void)animationEnded:(BOOL) transitionCompleted;
@end
系統(tǒng)調(diào)用上述協(xié)議的時(shí)候,參數(shù)是一個(gè)遵守UIViewControllerContextTransitioning
協(xié)議的上下文對象
@protocol UIViewControllerContextTransitioning <NSObject>
// 容器視圖充當(dāng)動畫序列期間所有其他視圖(包括消失和呈現(xiàn)的視圖控制器的視圖)的父視圖爵嗅。
@property(nonatomic, readonly) UIView *containerView;
//允許自定義過渡向容器視圖添加或刪除子視圖娇澎。對于除UIModalPresentationCustom樣式以外的模態(tài)表示樣式,此屬性的值始終為YES睹晒。
// 當(dāng)模式表示樣式為UIModalPresentationCustom時(shí)趟庄,如果過渡應(yīng)設(shè)置動畫,則值為YES伪很;否則岔激,則為NO。
// 使用此值可以確定是否需要對自定義過渡進(jìn)行動畫處理是掰,或者是否應(yīng)在不對更改進(jìn)行動畫處理的情況下將最終視圖安裝到容器中虑鼎。
@property(nonatomic, readonly, getter=isAnimated) BOOL animated;
// 這表明過渡當(dāng)前是否是交互式的。
@property(nonatomic, readonly, getter=isInteractive) BOOL interactive;
// 轉(zhuǎn)場是否取消
@property(nonatomic, readonly) BOOL transitionWasCancelled;
// 控制器過渡的表示樣式。
@property(nonatomic, readonly) UIModalPresentationStyle presentationStyle;
// 更新
- (void)updateInteractiveTransition:(CGFloat)percentComplete;
// 完成
- (void)finishInteractiveTransition;
// 取消
- (void)cancelInteractiveTransition;
// 暫停
- (void)pauseInteractiveTransition API_AVAILABLE(ios(10.0));
// 每當(dāng)轉(zhuǎn)換完成(或取消轉(zhuǎn)換)時(shí)炫彩,都必須調(diào)用此方法匾七。
// 通常,此方法由符合由轉(zhuǎn)換委托售賣的UIViewControllerAnimatedTransitioning協(xié)議的對象調(diào)用江兢。 對于純交互式過渡昨忆,應(yīng)由交互控制器調(diào)用。
- (void)completeTransition:(BOOL)didComplete;
//目前,只有兩個(gè)鍵
//-UITransitionContextToViewControllerKey,
// UITransitionContextFromViewControllerKey励幼。
//不應(yīng)操縱視圖,而應(yīng)使用viewForKey:獲取視圖性置。
- (nullable __kindof UIViewController *)viewControllerForKey:(UITransitionContextViewControllerKey)key;
//目前,系統(tǒng)僅定義了兩個(gè)鍵-
// UITransitionContextFromViewKey和UITransitionContextToViewKey
// 可能返回nil,這表明不應(yīng)該操作關(guān)聯(lián)的視圖控制器的視圖繁疤。
- (nullable __kindof UIView *)viewForKey:(UITransitionContextViewKey)key API_AVAILABLE(ios(8.0));
// 指示在過渡期間要應(yīng)用的旋轉(zhuǎn)量。
@property(nonatomic, readonly) CGAffineTransform targetTransform API_AVAILABLE(ios(8.0));
/*
此方法返回的矩形代表轉(zhuǎn)換開始時(shí)相應(yīng)視圖的大小秕狰。 對于已經(jīng)在屏幕上的視圖控制器稠腊,此矩形通常與容器視圖的框架矩形匹配。 對于即將顯示的視圖控制器鸣哀,此方法返回的值通常為CGRectZero架忌,因?yàn)橐晥D尚未顯示在屏幕上。
*/
- (CGRect)initialFrameForViewController:(UIViewController *)vc;
/*
此方法返回的矩形表示轉(zhuǎn)換結(jié)束時(shí)相應(yīng)視圖的大小我衬。 對于演示過程中涉及的視圖叹放,此方法返回的值可能是CGRectZero,但也可能是有效的框架矩形低飒。
*/
- (CGRect)finalFrameForViewController:(UIViewController *)vc;
@end
交互式的轉(zhuǎn)場動畫
想要?jiǎng)赢嬜兊乜梢越换シ浅:唵涡碜颍覀冎恍枰采w另一個(gè) UINavigationControllerDelegate
的方法:
- (id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController*)navigationController
interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>)animationController
{
return self.interactionController;
}
注意,在非交互式動畫效果中褥赊,該方法返回 nil糕档。
這里返回的 interaction controller 是 UIPercentDrivenInteractiveTransition 類的一個(gè)實(shí)例。
而關(guān)于UIViewControllerInteractiveTransitioning
@protocol UIViewControllerInteractiveTransitioning <NSObject>
/*
此方法的實(shí)現(xiàn)應(yīng)使用transitionContext參數(shù)中的數(shù)據(jù)為過渡配置用戶交互性拌喉,然后啟動動畫速那。 在跟蹤用戶互動時(shí),應(yīng)定期調(diào)用上下文對象的updateInteractiveTransition:方法尿背,以報(bào)告現(xiàn)在完成了多少轉(zhuǎn)換端仰。
如果事件指示用戶已取消轉(zhuǎn)換,請調(diào)用cancelInteractiveTransition方法田藐。 如果事件指示過渡已完成荔烧,請調(diào)用finishInteractiveTransition方法吱七。
*/
- (void)startInteractiveTransition:(id <UIViewControllerContextTransitioning>)transitionContext;
@optional
// 在交互部分完成后鹤竭,系統(tǒng)需要完成交互轉(zhuǎn)換的速度時(shí)調(diào)用。
@property(nonatomic, readonly) CGFloat completionSpeed;
// 當(dāng)系統(tǒng)需要?jiǎng)赢嬐瓿汕€以進(jìn)行交互式視圖控制器轉(zhuǎn)換時(shí)調(diào)用
@property(nonatomic, readonly) UIViewAnimationCurve completionCurve;
/*
當(dāng)過渡從開始就具有交互性時(shí)稚机,此屬性的值為YES颜凯。 當(dāng)過渡以非交互方式開始時(shí),該屬性為NO募壕。 但是代嗤,即使過渡開始時(shí)是非交互的硝逢,如果它實(shí)現(xiàn)UIViewControllerAnimatedTransitioning協(xié)議的interruptibleAnimatorForTransition:方法综芥,則以后也可能變?yōu)榻换ナ健?*/
@property (nonatomic, readonly) BOOL wantsInteractiveStart API_AVAILABLE(ios(10.0));
@end
UIPercentDrivenInteractiveTransition
UIKIT_EXTERN API_AVAILABLE(ios(7.0)) @interface UIPercentDrivenInteractiveTransition : NSObject <UIViewControllerInteractiveTransitioning>
// 這是在過渡開始時(shí)調(diào)用<UIViewControllerAnimatedTransitioning>`transitionDuration:`方法時(shí)返回的非交互持續(xù)時(shí)間额各。
@property (readonly) CGFloat duration;
/// 由updateInteractiveTransition指定的最后一個(gè)percentComplete值:
@property (readonly) CGFloat percentComplete;
//過渡動畫的速度傲醉。
/*
此屬性的默認(rèn)值為1.0吐咳,產(chǎn)生一個(gè)實(shí)時(shí)進(jìn)行的動畫沪羔。 可以更改此值以加快或減緩過渡中的動畫死嗦。 例如外盯,在過渡結(jié)束時(shí)或取消動畫時(shí)更改動畫速度狈邑,在這種情況下,您將在停止跟蹤用戶事件并要調(diào)用cancelInteractiveTransition或finishInteractiveTransition方法時(shí)設(shè)置速度蘸嘶。
速度是當(dāng)前動畫速度的乘數(shù)良瞧,因此,大于1.0的值會使動畫加速训唱,而小于1.0的值會使動畫減速褥蚯。 此屬性中的值必須始終大于0.0。
*/
@property (nonatomic,assign) CGFloat completionSpeed;
//指示交互式過渡的動畫完成曲線雪情。
@property (nonatomic,assign) UIViewAnimationCurve completionCurve;
/*
驅(qū)動動畫時(shí)要使用的時(shí)序曲線遵岩。
對于可中斷的動畫你辣,可以指定在繼續(xù)過渡時(shí)要使用的其他時(shí)序曲線提供者巡通。
*/
@property (nullable, nonatomic, strong)id <UITimingCurveProvider> timingCurve API_AVAILABLE(ios(10.0));
// 一個(gè)布爾值,指示動畫最初是否是交互式的舍哄。
//當(dāng)此屬性的值為YES時(shí)宴凉,交互式動畫將暫停播放,從而使您可以從頭開始驅(qū)動動畫表悬。 當(dāng)您想不交互地開始動畫時(shí)弥锄,可以將此屬性設(shè)置為NO。
@property (nonatomic) BOOL wantsInteractiveStart API_AVAILABLE(ios(10.0));
/*
這是調(diào)用上下文對象的pauseInteractiveTransition方法的便捷方法蟆沫。
您可以調(diào)用此方法籽暇,以便可以開始交互式驅(qū)動動畫。
例如饭庞,當(dāng)用戶的手指觸摸屏幕時(shí)戒悠,手勢處理程序?qū)⒄{(diào)用此方法以停止動畫,然后使用對觸摸位置的更改來更新percentComplete屬性舟山。
*/
- (void)pauseInteractiveTransition API_AVAILABLE(ios(10.0));
/*
調(diào)用上下文對象的updateInteractiveTransition:方法的便捷方法绸狐。
在跟蹤用戶事件時(shí)卤恳,代碼應(yīng)定期調(diào)用此方法以更新當(dāng)前進(jìn)度以完成過渡。
如果在跟蹤過程中寒矿,交互作用超過了您認(rèn)為表示過渡已完成或取消的閾值突琳,停止跟蹤事件并調(diào)用finishInteractiveTransition或cancelInteractiveTransition方法。
*/
- (void)updateInteractiveTransition:(CGFloat)percentComplete;
/*
調(diào)用上下文對象的cancelInteractiveTransition方法的便捷方法符相。
在跟蹤用戶交互時(shí)拆融,當(dāng)交互提示用戶希望取消或中止視圖控制器轉(zhuǎn)換時(shí),手勢識別器或事件處理代碼將調(diào)用此方法啊终。
例如冠息,如果用戶反轉(zhuǎn)了滑動方向,然后觸摸事件結(jié)束孕索,建議用戶決定是否進(jìn)行過渡逛艰,則可以調(diào)用此方法。
*/
- (void)cancelInteractiveTransition;
/*
這是調(diào)用上下文對象的finishInteractiveTransition方法的便捷方法搞旭。
在跟蹤用戶交互時(shí)散怖,如果交互表明轉(zhuǎn)換已完成,則手勢識別器或事件處理代碼應(yīng)調(diào)用此方法肄渗。
例如镇眷,如果用戶滑動手指,并且觸摸事件指示滑動距離超過了完成手勢所需的閾值翎嫡,則在相應(yīng)的觸摸事件結(jié)束時(shí)調(diào)用此方法欠动,以使系統(tǒng)知道它現(xiàn)在可以完成過渡。
*/
- (void)finishInteractiveTransition;
@end
參考文章
https://blog.csdn.net/hello_hwc/article/details/42580773
z