我不是很瞭解CALayer的display
和drawInContext
如何與視圖中的drawRect
相關。在iOS上,setNeedsDisplay確實不會導致drawRect被調用......除非CALayer的display或drawInContext最終調用drawRect?
如果我有一個NSTimer每隔1秒設置[self.view setNeedsDisplay]
,則每1秒調用一次drawRect
,如drawRect
內部的NSLog語句所示。
但是,如果我繼承CALayer並將其用於視圖,如果我使display
方法爲空,則現在不會調用drawRect
。 更新:但是每隔1秒調用一次display
,如NSLog語句所示。
如果我刪除空的display
方法並添加一個空的drawInContext
方法,再次,drawRect
永遠不會被調用。 更新:但是每隔1秒調用一次drawInContext
,如NSLog語句所示。
究竟發生了什麼?看起來display
可以有選擇地撥打drawInContext
和drawInContext
可以有選擇地以某種方式撥打drawRect
(怎麼辦?),但這裏真實的情況是什麼?
更新:有更多的線索答案:
我改變了CoolLayer.m
代碼如下:
-(void) display {
NSLog(@"In CoolLayer's display method");
[super display];
}
-(void) drawInContext:(CGContextRef)ctx {
NSLog(@"In CoolLayer's drawInContext method");
[super drawInContext:ctx];
}
所以,我們說,如果有一個月亮(作爲Core Graphics繪製的一個圓圈)在視圖中的位置(100,100)處,現在我將其更改爲位置(200,200),自然,我將調用[self.view setNeedsDisplay]
,現在,CALayer將根本沒有緩存用於新視圖圖像,就像我的drawRect
指示現在應如何顯示月亮。
即使如此,切入點是CALayer的的display
,然後CALayer的的drawInContext
:如果我在drawRect
設置一個斷點,調用堆棧顯示:
所以我們可以看到,CoolLayer的display
是先輸入CALayer的display
,然後輸入CoolLayer的drawInContext
,然後輸入CALayer的drawInContext
,儘管在這種情況下,新圖像不存在這樣的緩存。
然後最後,CALayer的drawInContext
調用代表的drawLayer:InContext
。該委託是視圖(FooView或UIView)...和drawLayer:InContext
是UIView中的默認實現(因爲我沒有覆蓋它)。終於,drawLayer:InContext
調用drawRect
。
所以我猜兩點:爲什麼它進入CALayer即使沒有緩存的圖像?因爲通過這種機制,圖像在上下文中繪製,並最終返回到display
,並且CGImage是從此上下文創建的,然後現在將其設置爲緩存的新圖像。這就是CALayer緩存圖像的方式。
我不太確定的另一件事是:如果[self.view setNeedsDisplay]
總是觸發drawRect
被調用,那麼何時可以使用CALayer中的緩存圖像?可能是...在Mac OS X上,當另一個窗口覆蓋一個窗口時,現在頂部窗口被移開。現在我們不需要調用drawRect
來重繪所有內容,但可以使用CALayer中的緩存圖像。或者在iOS上,如果我們停止應用程序,執行其他操作,然後返回應用程序,則可以使用緩存圖像,而不是調用drawRect
。但如何區分這兩種「髒」?一個是「未知的骯髒」 - 月亮需要重新繪製,如邏輯(它也可以使用隨機數字作爲座標)。其他類型的骯髒是它被掩蓋或使其消失,現在需要重新顯示。
CALayer如何發揮作用? –
在文檔中明確指出,'setNeedsDisplay'只適用於UIKit和Core Graphics繪圖,我相信髒視圖更新對它們都是有效的。如文檔所述,請注意這對CAEAGLLayer無效。 –
問題是如果我們使用'setNeedsDisplay',但是覆蓋CALayer的方法,那麼'drawRect'不會被調用,爲什麼? –