2010-09-24 65 views
15

我找不到一個像樣的答案來解釋這兩個函數之間的區別。 什麼時候每個人都會打電話,以及一個人和另一個人有什麼不同?drawrect vs layoutsubviews - NSView - 可可觸摸

例如,我不能只是佈局我的意見裏面drawrect?

感謝

回答

56

-layoutSubviews是,如果已經設置了「需要的佈局」(使用-setNeedsLayout-layoutIfNeeded叫,或者當視圖邊界改變時自動)。用它來定位 您的看法 [編輯:用它來定位子視圖]。

-drawRect:-displayIfNeeded如果「需要顯示」標誌(使用-setNeedsDisplay,或如果設置view.contentMode = UIViewContentModeRedraw自動)設定調用。

-layoutIfNeeded-displayIfNeeded都是在UIKit/CoreAnimation自動調用之前繪製屏幕;你很少需要直接打電話給他們。

可以在-drawRect:定位您的子視圖(你甚至可以添加子視圖!),但是這是不明智的:

  • 默認情況下,-setNeedsDisplay不上界的變化自動調用。
  • 實現-drawRect:降低性能(UIKit/CoreAnimation必須爲您創建一個位圖支持的圖形上下文);只有在需要執行自定義繪圖時才這樣做。
  • 您需要重新繪製-drawRect:中的視圖。繪圖很昂貴。移動視圖很便宜。
  • UIKit/CoreAnimation可能會執行佈局過程,然後執行繪圖過程。 CoreAnimation可以使用佈局信息來決定哪些視圖需要繪製(例如,它可以忽略不透明的子視圖,離屏視圖或clipToBounds = YES視圖邊界之外的子視圖遮擋的視圖;或者它只能繪製一個子視圖的子視圖大視圖)。如果在繪製過程中移動視圖,CoreAnimation可能無法正確繪製它們。

編輯:有些時候我清醒,更詳細:

什麼是「顯示」和「畫」的區別?顯示由-[CALayer display]完成;默認的實現爲(大約)

  • 如果該層的委託迴應-displayLayer:,調用[self.delegate displayLayer:self]-displayLayer:應該設置layer.content到(例如)一CGImage,
  • 否則,如果層的委託迴應-drawLayer:inContext:,建立一個位圖支持的情況下,打電話[self.delegate drawLayer:self inContext:context],並且輸出保存到layer.content(輸出實際上是一個CABackingStore ,這大概是一個私人API)
  • 否則,不改變layer.content

視圖是層的委託,這樣你就可以實現-[MyView displayLayer:]代替,並做一些有趣的東西一樣

  • self.layer.contents = (id)([UIImage imageNamed:@"foo"].CGImage)(是的UIImageView做大致的)
  • 無操作,以防止任何「繪圖」。如果你已經分類了,這可能會很有用。 UIToolbar並希望爲其提供透明背景。 (這也可以防止CGContext上/ CABackingStore的創建。)
  • 移動子視圖周圍沒有性能損失(但它仍然不是理由的好主意以上)。
+0

偉大的答案。謝謝! – Idan 2010-09-25 11:39:14

-2

也許我不知道所有的答案,但我可以說你是: - 當setNeedDisplay被稱爲

的drawRect被稱爲 - 當視圖框改變 layoutSubviews被稱爲大多數時候你不會使用layoutSubviews。

可能還有其他案件,但它可以給你一個第一塊答案^^

好運的

+0

請給出更詳細的在你的說法,「大部分的時間你不會用layoutSubviews。」 – 2013-08-29 03:40:18