CALayer 以及時間模型

2021-07-10 08:50:18 字數 4237 閱讀 1698

我們都知道uiview是mvc中的view.uiview的職責在於介面的顯示和介面事件的處理.每乙個view的背後都有乙個layer(可以通過view.layer進行訪問),layer是用於介面顯示的.calayer屬於quartzcore框架,非常重要,但並沒有想象中的那麼好理解.我們通常操作的用於顯示的layer在core animation這層的概念中其實擔當的是資料模型model的角色,它並不直接做渲染的工作.關於layer,之前從座標系的角度分析過,這次則側重於它的時間系統.

1.layer的渲染架構

layer也和view一樣存在著乙個層級樹狀結構,稱之為圖層樹(layer tree),直接建立的或者通過uiview獲得的(view.layer)用於顯示的圖層樹,稱之為模型樹(model tree),模型樹的背後還存在兩份圖層樹的拷貝,乙個是呈現樹(presentation tree),乙個是渲染樹(render tree). 呈現樹可以通過普通layer(其實就是模型樹)的layer.presentationlayer獲得,而模型樹則可以通過modellayer屬性獲得(詳情文件).模型樹的屬性在其被修改的時候就變成了新的值,這個是可以用**直接操控的部分;呈現樹的屬性值和動畫執行過程中介面上看到的是一致的.而渲染樹是私有的,你無法訪問到,渲染樹是對呈現樹的資料進行渲染,為了不阻塞主線程,渲染的過程是在單獨的程序或執行緒中進行的,所以你會發現animation的動畫並不會阻塞主線程.

2.事務管理

sublayer=[[

calayer

alloc

]init

];sublayer

.frame

=cgrectmake(0

,0,300

,300

);sublayer

.backgroundcolor=[[

uicolor

redcolor

]cgcolor];[

self

.view

.layer

addsublayer:

sublayer

];

所有的非root layer在設定animatable properties的時候都存在著隱式動畫,預設的duration是0.25秒.

sublayer

.position

=cgpointmake

(300

,400

);

像上面這段**當下乙個runloop開始的時候並不是直接將sublayer的position變成(300,400)的,而是有個移動的動畫進行過渡完成的.

顯式事務的使用如下:

[

catransaction

begin

];...

[catransaction

commit

];

事務可以巢狀.當事務巢狀時候,只有當最外層的事務commit了之後,整個動畫才開始.

可以通過catransaction來設定乙個事務級別的動畫屬性,覆蓋隱式動畫的相關屬性,比如覆蓋隱式動畫的duration,timingfunction.如果是顯式動畫沒有設定duration或者timingfunction,那麼ca事務設定的這些引數也會對這個顯式動畫起作用.

還可以設定completionblock,當當前catransaction的所有動畫執行結束後, completionblock會被呼叫.

3.時間系統

calayer實現了camediatiming協議. calayer通過camediatiming協議實現了乙個有層級關係的時間系統.除了calayer,caanimation也採納了此協議,用來實現動畫的時間系統. 

在ca中,有乙個absolute time(絕對時間)的概念,可以通過cacurrentmediatime()獲得,其實這個絕對時間就是將mach_absolute_time()轉換成秒後的值.這個時間和系統的uptime有關,系統重啟後cacurrentmediatime()會被重置. 

就和座標存在相對座標一樣,不同的實現了camediatiming協議的存在層級關係的物件也存在相對時間,經常需要進行時間的轉換,calayer提供了兩個時間轉換的方法:

-

(cftimeinterval

)converttime:

(cftimeinterval)t

fromlayer:

(calayer*)

l;-(

cftimeinterval

)converttime:

(cftimeinterval)t

tolayer:

(calayer*)

l;

現在來重點研究camediatiming協議中幾個重要的屬性.

begintime

無論是圖層還是動畫,都有乙個時間線timeline的概念,他們的begintime是相對於父級物件的開始時間. 雖然蘋果的文件中沒有指明,但是通過**測試可以發現,預設情況下所有的calayer圖層的時間線都是一致的,他們的begintime都是0,絕對時間轉換到當前layer中的時間大小就是絕對時間的大小.所以對於圖層而言,雖然建立有先後,但是他們的時間線都是一致的(只要不主動去修改某個圖層的begintime),所以我們可以想象成所有的圖層預設都是從系統重啟後開始了他們的時間線的計時.

但是動畫的時間線的情況就不同了,當乙個動畫建立好,被加入到某個layer的時候,會先被拷貝乙份出來用於加入當前的圖層,在ca事務被提交的時候,如果圖層中的動畫的begintime為0,則begintime會被設定為當前圖層的當前時間,使得動畫立即開始.如果你想某個直接加入圖層的動畫稍後執行,可以通過手動設定這個動畫的begintime,但需要注意的是這個begintime需要為 cacurrentmediatime()+延遲的秒數,因為begintime是指其父級物件的時間線上的某個時間,這個時候動畫的父級物件為加入的這個圖層,圖層當前的時間其實為[layer converttime:cacurrentmediatime() fromlayer:nil],其實就等於cacurrentmediatime(),那麼再在這個layer的時間線上往後延遲一定的秒數便得到上面的那個結果.

timeoffset

這個timeoffset可能是這幾個屬性中比較難理解的乙個,官方的文件也沒有講的很清楚. local time也分成兩種一種是active local time 一種是basic local time.

timeoffset則是active local time的偏移量. 

你將乙個動畫看作乙個環,timeoffset改變的其實是動畫在環內的起點,比如乙個duration為5秒的動畫,將timeoffset設定為2(或者7,模5為2),那麼動畫的執行則是從原來的2秒開始到5秒,接著再0秒到2秒,完成一次動畫.

speed

speed屬性用於設定當前物件的時間流相對於父級物件時間流的流逝速度,比如乙個動畫begintime是0,但是speed是2,那麼這個動畫的1秒處相當於父級物件時間流中的2秒處. speed越大則說明時間流逝速度越快,那動畫也就越快.比如乙個speed為2的layer其所有的父輩的speed都是1,它有乙個sublayer,speed也為2,那麼乙個8秒的動畫在這個執行於這個sublayer只需2秒(8 / (2 * 2)).所以speed有疊加的效果.

fillmode

fillmode的作用就是決定當前物件過了非active時間段的行為. 比如動畫開始之前,動畫結束之後。如果是乙個動畫caanimation,則需要將其removedoncompletion設定為no,要不然fillmode不起作用. 下面來講各個fillmode的意義 

kcafillmoderemoved 這個是預設值,也就是說當動畫開始前和動畫結束後,動畫對layer都沒有影響,動畫結束後,layer會恢復到之前的狀態 

kcafillmodeforwards 當動畫結束後,layer會一直保持著動畫最後的狀態 

kcafillmodebackwards 這個和kcafillmodeforwards是相對的,就是在動畫開始前,你只要將動畫加入了乙個layer,layer便立即進入動畫的初始狀態並等待動畫開始.你可以這樣設定測試**,將乙個動畫加入乙個layer的時候延遲5秒執行.然後就會發現在動畫沒有開始的時候,只要動畫被加入了layer,layer便處於動畫初始狀態 

kcafillmodeboth 理解了上面兩個,這個就很好理解了,這個其實就是上面兩個的合成.動畫加入後開始之前,layer便處於動畫初始狀態,動畫結束後layer保持動畫最後的狀態.

其他的一些引數都是比較容易理解的.

CALayer及時間模型

我們都知道uiview是mvc中的view.uiview的職責在於介面的顯示和介面事件的處理.每乙個view的背後都有乙個layer 可以通過view.layer進行訪問 layer是用於介面顯示的.calayer屬於quartzcore框架,非常重要,但並沒有想象中的那麼好理解.我們通常操作的用於...

Linux修改時間以及時區

1.關於時間目錄 usr share zoneinfo 關於各個時區的的檔案用於ln fs到 etc localtime中的 etc localtime 硬體時區 etc sysconfig clock 系統時區 2.修改時間及時區的工具 date 修改系統時間以及系統時區 hwclock 修改硬體...

R語言 時間序列的建立及時間序列模型

一 時間序列的建立 時間序列的建立函式為 ts 函式的引數列表如下 ts data na,start 1,end numeric frequency 1,deltat 1,ts.eps getoption ts.eps class names 引數說明 data 這個必須是乙個矩陣,或者向量,再或者...