CALayer之presentationLayer和ModelLayer

CALayer的屬性行為其實很不正常,因為改變一個圖層的屬性并沒有立刻生效,而是通過一段時間漸變更新余指。這是怎么做到的呢醉途?
當你改變一個圖層的屬性矾瑰,屬性值的確是立刻更新的(如果你讀取它的數(shù)據(jù),你會發(fā)現(xiàn)它的值在你設(shè)置它的那一刻就已經(jīng)生效了)隘擎,但是屏幕上并沒有馬上發(fā)生改變殴穴。這是因為你設(shè)置的屬性并沒有直接調(diào)整圖層的外觀,相反货葬,他只是定義了圖層動畫結(jié)束之后將要變化的外觀采幌。
當設(shè)置CALayer的屬性,實際上是在定義當前事務(wù)結(jié)束之后圖層如何顯示的模型震桶。Core Animation扮演了一個控制器的角色休傍,并且負責根據(jù)圖層行為和事務(wù)設(shè)置去不斷更新視圖的這些屬性在屏幕上的狀態(tài)。
我們討論的就是一個典型的微型MVC模式蹲姐。CALayer是一個連接用戶界面(就是MVC中的view)虛構(gòu)的類磨取,但是在界面本身這個場景下,CALayer的行為更像是存儲了視圖如何顯示和動畫的數(shù)據(jù)模型柴墩。實際上忙厌,在蘋果自己的文檔中,圖層樹通常都是值的圖層樹模型江咳。
在iOS中逢净,屏幕每秒鐘重繪60次。如果動畫時長比60分之一秒要長歼指,Core Animation就需要在設(shè)置一次新值和新值生效之間爹土,對屏幕上的圖層進行重新組織。這意味著CALayer除了“真實”值(就是你設(shè)置的值)之外东臀,必須要知道當前顯示在屏幕上的屬性值的記錄着饥。
每個圖層屬性的顯示值都被存儲在一個叫做呈現(xiàn)圖層的獨立圖層當中,他可以通過-presentationLayer方法來訪問惰赋。這個呈現(xiàn)圖層實際上是模型圖層的復(fù)制宰掉,但是它的屬性值代表了在任何指定時刻當前外觀效果。換句話說赁濒,你可以通過呈現(xiàn)圖層的值來獲取當前屏幕上真正顯示出來的值(圖1)轨奄。
除了圖層樹,另外還有呈現(xiàn)樹拒炎。呈現(xiàn)樹通過圖層樹中所有圖層的呈現(xiàn)圖層所形成挪拟。注意呈現(xiàn)圖層僅僅當圖層首次被提交(就是首次第一次在屏幕上顯示)的時候創(chuàng)建,所以在那之前調(diào)用-presentationLayer將會返回nil击你。
你可能注意到有一個叫做–modelLayer的方法玉组。在呈現(xiàn)圖層上調(diào)用–modelLayer將會返回它正在呈現(xiàn)所依賴的CALayer谎柄。通常在一個圖層上調(diào)用-modelLayer會返回–self(實際上我們已經(jīng)創(chuàng)建的原始圖層就是一種數(shù)據(jù)模型)。


圖1 一個移動的圖層是如何通過數(shù)據(jù)模型呈現(xiàn)的

大多數(shù)情況下惯雳,你不需要直接訪問呈現(xiàn)圖層朝巫,你可以通過和模型圖層的交互,來讓Core Animation更新顯示石景。兩種情況下呈現(xiàn)圖層會變得很有用劈猿,一個是同步動畫,一個是處理用戶交互潮孽。
如果你在實現(xiàn)一個基于定時器的動畫揪荣,而不僅僅是基于事務(wù)的動畫,這個時候準確地知道在某一時刻圖層顯示在什么位置就會對正確擺放圖層很有用了往史。
如果你想讓你做動畫的圖層響應(yīng)用戶輸入仗颈,你可以使用 -hitTest: 方法來判斷指定圖層是否被觸摸,這時候?qū)Τ尸F(xiàn)圖層而不是模型圖層調(diào)用-hitTest:會顯得更有意義怠堪,因為呈現(xiàn)圖層代表了用戶當前看到的圖層位置揽乱,而不是當前動畫結(jié)束之后的位置。

我們可以用一個簡單的案例來證明后者(見清單1)粟矿。在這個例子中凰棉,點擊屏幕上的任意位置將會讓圖層平移到那里。點擊圖層本身可以隨機改變它的顏色陌粹。我們通過對呈現(xiàn)圖層調(diào)用-hitTest:來判斷是否被點擊撒犀。
如果修改代碼讓 -hitTest: 直接作用于colorLayer而不是呈現(xiàn)圖層,你會發(fā)現(xiàn)當圖層移動的時候它并不能正確顯示掏秩。這時候你就需要點擊圖層將要移動到的位置而不是圖層本身來響應(yīng)點擊(這就是為什么用呈現(xiàn)圖層來響應(yīng)交互的原因)或舞。

清單1, 使用presentationLayer圖層來判斷當前圖層位置

@interface MainCALayerVC ()
@property(nonatomic,strong)CALayer*layerOne;
@property(nonatomic,strong)CALayer*colorLayer;
@end
@implementation MainCALayerVC

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor=[UIColor  orangeColor];

    self.layerOne=[CALayer layer];
    self.layerOne.frame=CGRectMake(0, 0, 40, 40);
    self.layerOne.position=CGPointMake(30, NavHeight+30);
    self.layerOne.backgroundColor=[UIColor greenColor].CGColor;
    [self.view.layer addSublayer:self.layerOne];
    
    self.colorLayer=[CALayer layer];
    self.colorLayer.frame = CGRectMake(0, 0, 100, 100);
    self.colorLayer.position = CGPointMake(self.view.bounds.size.width / 2, self.view.bounds.size.height /2);
    self.colorLayer.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:self.colorLayer];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint point = [[touches anyObject] locationInView:self.view];
    if ([self.colorLayer.presentationLayer hitTest:point]) {
        CGFloat red = arc4random() / (CGFloat)INT_MAX;
        CGFloat green = arc4random() / (CGFloat)INT_MAX;
        CGFloat blue = arc4random() / (CGFloat)INT_MAX;
        self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:bluealpha:1.0].CGColor;
   }else if ([self.layerOne.modelLayer hitTest:point])//或者[self.layerOne hitTest:point]
   {
       CGFloat red = arc4random() / (CGFloat)INT_MAX;
       CGFloat green = arc4random() / (CGFloat)INT_MAX;
       CGFloat blue = arc4random() / (CGFloat)INT_MAX;
       self.layerOne.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;
   }else {
        [CATransaction begin];
        [CATransaction setAnimationDuration:4.0];
        self.colorLayer.position = point;
        CGPoint point1=point;
        point1.x=point.x+100;
        self.layerOne.position=point1;
        [CATransaction commit];
   }
}

可以觀察到:在移動的過程中,若點擊self.colorLayer時蒙幻,顏色會立馬變化映凳。而點擊self.layerOne時,則不會變化邮破,不移動的時候才變化诈豌。
至此,你了解了呈現(xiàn)和模型圖層抒和,以及Core Animation是如何通過它們來判斷出圖層當前位置以及將要到達的位置矫渔。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市摧莽,隨后出現(xiàn)的幾起案子庙洼,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 223,126評論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件油够,死亡現(xiàn)場離奇詭異蚁袭,居然都是意外死亡,警方通過查閱死者的電腦和手機叠聋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評論 3 400
  • 文/潘曉璐 我一進店門撕阎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人碌补,你說我怎么就攤上這事∶奕模” “怎么了厦章?”我有些...
    開封第一講書人閱讀 169,941評論 0 366
  • 文/不壞的土叔 我叫張陵,是天一觀的道長照藻。 經(jīng)常有香客問我袜啃,道長,這世上最難降的妖魔是什么幸缕? 我笑而不...
    開封第一講書人閱讀 60,294評論 1 300
  • 正文 為了忘掉前任群发,我火速辦了婚禮,結(jié)果婚禮上发乔,老公的妹妹穿的比我還像新娘熟妓。我一直安慰自己,他們只是感情好栏尚,可當我...
    茶點故事閱讀 69,295評論 6 398
  • 文/花漫 我一把揭開白布起愈。 她就那樣靜靜地躺著,像睡著了一般译仗。 火紅的嫁衣襯著肌膚如雪抬虽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,874評論 1 314
  • 那天纵菌,我揣著相機與錄音阐污,去河邊找鬼。 笑死咱圆,一個胖子當著我的面吹牛笛辟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播闷堡,決...
    沈念sama閱讀 41,285評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼隘膘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了杠览?” 一聲冷哼從身側(cè)響起弯菊,我...
    開封第一講書人閱讀 40,249評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后管钳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钦铁,經(jīng)...
    沈念sama閱讀 46,760評論 1 321
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,840評論 3 343
  • 正文 我和宋清朗相戀三年才漆,在試婚紗的時候發(fā)現(xiàn)自己被綠了牛曹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,973評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡醇滥,死狀恐怖黎比,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鸳玩,我是刑警寧澤阅虫,帶...
    沈念sama閱讀 36,631評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站不跟,受9級特大地震影響颓帝,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜窝革,卻給世界環(huán)境...
    茶點故事閱讀 42,315評論 3 336
  • 文/蒙蒙 一购城、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧虐译,春花似錦瘪板、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至拴泌,卻和暖如春魏身,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蚪腐。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評論 1 275
  • 我被黑心中介騙來泰國打工箭昵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人回季。 一個月前我還...
    沈念sama閱讀 49,431評論 3 379
  • 正文 我出身青樓家制,卻偏偏與公主長得像,于是被迫代替她去往敵國和親泡一。 傳聞我的和親對象是個殘疾皇子颤殴,可洞房花燭夜當晚...
    茶點故事閱讀 45,982評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 書寫的很好,翻譯的也棒鼻忠!感謝譯者涵但,感謝感謝! iOS-Core-Animation-Advanced-Techni...
    錢噓噓閱讀 2,304評論 0 6
  • 前言 本文只要描述了iOS中的Core Animation(核心動畫:隱式動畫、顯示動畫)矮瘟、貝塞爾曲線瞳脓、UIVie...
    GitHubPorter閱讀 3,641評論 7 11
  • 轉(zhuǎn)載:http://www.cnblogs.com/jingdizhiwa/p/5601240.html 1.ge...
    F麥子閱讀 1,551評論 0 1
  • 在iOS中隨處都可以看到絢麗的動畫效果,實現(xiàn)這些動畫的過程并不復(fù)雜澈侠,今天將帶大家一窺ios動畫全貌劫侧。在這里你可以看...
    每天刷兩次牙閱讀 8,517評論 6 30
  • 2017.5.2星期二 晴 從前,在遙遠的國度有一位公主哨啃,要找能屠龍的勇士做丈夫 一時間烧栋,群雄并起,卻紛紛...
    紫瀑閱讀 230評論 0 3