每個 UIView 內(nèi)部都有一個 CALayer 在背后提供內(nèi)容的繪制和顯示颠锉,并且 UIView 的尺寸樣式都由內(nèi)部的 Layer 所提供祟峦。兩者都有樹狀層級結(jié)構(gòu),layer 內(nèi)部有 SubLayers副渴,View 內(nèi)部有 SubViews.但是 Layer 比 View 多了個AnchorPoint
在 View顯示的時(shí)候翼悴,UIView 做為 Layer 的CALayerDelegate,View 的顯示內(nèi)容取決于內(nèi)部的 CALayer 的 display
CALayer 是默認(rèn)修改屬性支持隱式動畫的,在給 UIView 的 Layer 做動畫的時(shí)候隔缀,View 作為 Layer 的代理题造,Layer 通過 actionForLayer:forKey:向 View請求相應(yīng)的action(動畫行為)
layer 內(nèi)部維護(hù)著三分layer tree,分別是 presentLayer Tree(動畫樹),modeLayer Tree(模型樹), Render Tree (渲染樹),在做 iOS動畫的時(shí)候,我們修改動畫的屬性猾瘸,在動畫的其實(shí)是 Layer 的 presentLayer的屬性值,而最終展示在界面上的其實(shí)是提供 View的modelLayer
兩者最明顯的區(qū)別是 View可以接受并處理事件界赔,而 Layer 不可以
隱式動畫與顯示動畫:
隱式動畫
不需要初始化任何類,系統(tǒng)自己處理的動畫屬性
粗淺的可以理解為牵触,系統(tǒng)默認(rèn)淮悼,自帶的效果
這其實(shí)就是所謂的隱式動畫。之所以叫隱式是因?yàn)槲覀儾]有指定任何動畫的類 型揽思。我們僅僅改變了一個屬性袜腥,然后Core Animation來決定如何并且何時(shí)去做動 畫。Core Animaiton同樣支持顯式動畫钉汗,
核心動畫的隱式動畫模型假定所有動畫圖層屬性的變化應(yīng)該是漸進(jìn)的和異步的羹令。
動態(tài)的動畫場景可以在沒有顯式的動畫圖層時(shí)候?qū)崿F(xiàn)。
改變動畫顯示的圖層的屬性將會導(dǎo)致圖層隱式把舊值動畫顯示為新值损痰,雖然動畫是持續(xù)的福侈,但是設(shè)置新的目標(biāo)值會導(dǎo)致圖層從當(dāng)前狀態(tài)動畫過度到新的目標(biāo)值
OrderSearchVC *search = [[OrderSearchVC alloc] init];
[self.navigationController pushViewController:search animated:YES];
根據(jù)我粗淺的理解,「隱式動畫」中的所謂「隱式」徐钠,是相對于「顯式動畫」中的顯式而言的癌刽。
實(shí)現(xiàn)顯式動畫時(shí),往往會創(chuàng)建一個動畫對象,譬如CAAnimation显拜、CABasicAnimation衡奥、CAKeyframeAnimation,然后通過CALayer#addAnimation(_:forKey:)方法該動畫對象綁定到layer中远荠,
顯式動畫
核心動畫同事提供了一個顯示動畫模型矮固。該顯式動畫模型需要你創(chuàng)建一個動畫對象,并設(shè)置開始值和結(jié)束的值譬淳,顯示動畫不會開始執(zhí)行档址,直到你把該動畫應(yīng)用到某個圖層上面
CABasicAnimation *opAnim = [CABasicAnimation animationWithKeyPath:@opacity];
opAnim.duration = 1.0;
opAnim.fromValue = [NSNumber numberWithFloat:0.1];
opAnim.toValue= [NSNumber numberWithFloat:1.0];
opAnim.repeatCount = 1;
[view.layer addAnimation:opAnim forKey:@animateOpacity];
iOS 動畫會改變frame嗎?
在iOS開發(fā)中邻梆,動畫本身通常不會直接改變視圖的frame
屬性守伸,但動畫的效果會讓視圖看起來像是在移動、縮放浦妄、旋轉(zhuǎn)或改變透明度等尼摹。這種視覺上的變化是通過改變視圖層的屬性(如CALayer
的position
、bounds
剂娄、transform
等)來實(shí)現(xiàn)的蠢涝,而不是直接修改frame
。
幀(Frame)與層(Layer)
-
幀(Frame):
UIView
的frame
屬性定義了視圖在其父視圖坐標(biāo)系統(tǒng)中的位置和大小阅懦。這是一個矩形和二,通常用CGRect
結(jié)構(gòu)體表示,包含origin
(原點(diǎn)耳胎,即左上角的位置)和size
(尺寸)惯吕。 -
層(Layer):
UIView
的底層是由CALayer
實(shí)現(xiàn)的。CALayer
提供了對視圖內(nèi)容渲染的底層支持场晶,包括位置混埠、大小、透明度诗轻、邊框钳宪、陰影等屬性的管理。動畫效果通常是通過修改CALayer
的屬性來實(shí)現(xiàn)的扳炬。
動畫與frame
動畫執(zhí)行:當(dāng)你對視圖應(yīng)用動畫(如使用
UIView
的動畫塊或Core Animation
框架)時(shí)吏颖,你通常會修改與動畫相關(guān)的層屬性(如position
、bounds
恨樟、transform
等)半醉。這些變化會立即反映在視覺上,但frame
屬性可能不會自動更新以反映這些變化劝术。frame
與bounds
/center
:frame
是相對于父視圖的缩多,而bounds
和center
是相對于視圖自身的呆奕。當(dāng)你通過動畫改變視圖的位置時(shí)(例如,通過修改center
或position
)衬吆,雖然視圖在屏幕上移動了梁钾,但其frame
的origin
可能并沒有立即更新(因?yàn)樗匀槐硎驹诟敢晥D坐標(biāo)系中的原始位置)。但是逊抡,如果你通過修改frame
本身來移動視圖(而不是通過動畫)姆泻,則frame
會立即更新,但這種情況下不會有動畫效果冒嫡。動畫完成后的狀態(tài):如果你通過動畫改變了視圖的位置或大小拇勃,并希望這些變化在動畫完成后保持下來,你需要確保在動畫開始前或在動畫的完成回調(diào)中手動更新
frame
屬性(如果需要的話)孝凌。不過方咆,在很多情況下,由于CALayer
的屬性(如position
)已經(jīng)改變胎许,所以frame
可能會間接地“看起來”已經(jīng)更新峻呛,即使你沒有顯式地設(shè)置它。
結(jié)論
動畫本身不會直接改變frame
辜窑,但動畫的效果可能會讓視圖看起來像是改變了位置或大小。如果你需要確保動畫完成后的狀態(tài)與動畫過程中的狀態(tài)一致寨躁,你可能需要手動更新frame
或其他相關(guān)屬性穆碎。然而,在大多數(shù)情況下职恳,通過修改CALayer
的屬性(如position
所禀、bounds
、transform
)來實(shí)現(xiàn)動畫效果就足夠了放钦,因?yàn)閕OS的視圖系統(tǒng)會在底層處理好這些變化與frame
之間的關(guān)系色徘。
作者:不簡單的風(fēng)度
鏈接:http://www.reibang.com/p/ed40da9303b1
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)操禀,非商業(yè)轉(zhuǎn)載請注明出處褂策。