2012-03-21 66 views
7

我將CALayer子類化爲在方法中提供我自己的繪圖。爲了優化,我呼籲-[MyLayer setNeedsDisplayInRect:]而不是-[MyLayer setNeedsDisplay]。在繪圖方法中,我得到應該通過CGContextGetClipBoundingBox()重畫的矩形。- [CALayer setNeedsDisplayInRect:]導致整個圖層被重新繪製

如果我使用此層作爲基底層的UIView每件事情都按預期工作。問題出現了,只要我將自定義圖層用作其他CALayer的子圖層即可。比CGContextGetClipBoundingBox()總是返回該層邊界的矩形。

任何想法?

[編輯]

看來,是沒有保證的,該CALayer的內容緩存,只有髒的部分被重新繪製。我做了一個小測試,並將需要顯示的矩形存儲爲一個單獨的屬性。結果是,只有這部分在屏幕上可見。

我現在將渲染到圖像上下文並將該圖像保存爲緩存。在繪製方法中,我只會顯示緩存的圖像。

+0

非視圖圖層的「masksToBounds」屬性是否設置爲「YES」?如果不是,他們不會剪輯的充分理由。 – MrMage 2012-03-21 17:28:24

+0

不幸的是,這並沒有解決它。問題是,'CGContextGetClipBoundingBox()'返回圖層的邊界,而不是Apple所記錄的需要更新的區域:*希望查找要繪製的實際區域的子類可以調用CGContextGetClipBoundingBox。* [drawInCOntext:] (https://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html#//apple_ref/occ/instm/CALayer/drawInContext :) – 2012-03-22 09:56:18

+0

你有沒有去過這個底部?我有同樣煩人的問題。 – mprivat 2012-05-08 21:55:09

回答

6

不幸的是,Apple的文檔是衝突的,因爲-setNeedsDisplayInRect上的文檔沒有指出該方法是否在實踐中有效。根據我自己的經驗,this technote套平直:

注,因爲iPhone/iPod的觸摸/ iPad的更新它的屏幕,如果你調用-setNeedsDisplayInRect整個視圖將重繪方式:或-setNeedsDisplay :。

這就是說,如果您認爲由於多餘的繪圖而撞牆,有很多事情可以考慮。

  • 如果繪製圖像,您可以進行的最大性能改進是使用您繪製的相同尺寸的圖像。如果它們不是,請嘗試通過將圖像渲染到離屏位圖上下文來緩存圖像,並在稍後將其恢復。
  • 查看CALayer上的shouldRasterize屬性。如果試圖操縱一個圖層的子圖層可能構成一個複雜的圖層層次結構,這可能是天賜良機。通過勾選核心動畫設備中的Color Hits Green and Misses Red框,確保查看您在儀器中的操作。如果你看到很多紅色,很可能會使用shouldRasterize而不是它的幫助。
  • 甚至比shouldRasterize更好的是平整您的圖層層次結構,因爲這樣可以避免shouldRasterize實時平鋪層次結構時產生的額外開銷。當然這並不總是可能的,但不要害怕嘗試:)
  • 如果您正在繪製圖像,請嘗試使用blending mode進行試驗。如果您恰好在繪製不透明的圖像,則不需要使用普通的源代碼(使用讀/寫帶寬)。試試kCGBlendModeCopy,它可以讓你消除讀取帶寬開銷。
  • 查看CGLayerRef,它允許您將核心圖形輸出跨各種調用緩存到繪圖方法。我的經驗是,除非你正在做一些硬核像素推動,否則這最終會比重繪更昂貴。見this有趣的閱讀。
  • 首先,樂器是你的朋友。查看過去WWDC的一些視頻(2012, 2011, and 2010);他們都有關於如何微調錶現的很好的信息。

如果我所說的話沒有意義,請隨時提出任何問題。

+0

有沒有辦法強迫低級的CALayers把他們的重畫/光柵化直到其他UIViews掩蓋它們而不是他們先發制人爲止? – Confused 2014-09-23 14:57:18