2012-05-12 29 views
1

我正在自定義我的drawRect:方法,如果它已被「加載」(由於我從WebView中抓取它,因此需要花費幾秒鐘的時間加載),因此可用於繪製NSImage,並推遲繪製圖像直到稍後如果圖像尚未加載。從-drawRect中調用-setNeedsDisplay:YES?

- (void)drawRect:(NSRect)dirtyRect 
{ 
    NSImage *imageToDraw = [self cachedImage]; 
    if (imageToDraw != nil) { 
     [imageToDraw drawInRect:dirtyRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil]; 
    } else { 
     //I need help here 
     [self setNeedsDisplay:YES]; 
    } 
} 

我的問題是如何做後者。 [self cachedImage]如果圖像不可用,則返回nil,但隨時可能在接下來的幾秒內變得可用,並且當時我想繪製它,因爲自定義視圖已經在屏幕上。

我最初的直覺是嘗試調用[self setNeedsDisplay:YES];如果圖像不可用,希望它會告訴可可在下一次再次調用drawRect(並且一次又一次,直到圖像被繪製),但是這是行不通的。

任何指針,我可以從哪裏去?


編輯:

我非常清楚的委託方法WebView火的時候的loadRequest已處理完畢。然而,由於其他應用程序的結構,使用這些應用程序將非常困難,但考慮到當前的答案,我想我會嘗試以某種方式使用它們。 (也注意到,我的drawRect:方法是重量比較輕,也被什麼除了我已經有上面的代碼。)

我現在有每個自定義數據問同樣的WebView生成圖像約10+自定義視圖爲他們每個人。同時,我從NSCache中抓取圖像(使用與每個自定義視圖對應的標識符),如果它不存在或需要更新,則創建該圖像,如果尚不可用,則返回nil。因此,從- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame或其他方法調用[view setNeedsDisplay:YES]並不容易。

+1

到底是如何,你抓住那個圖像? – DrummerB

+0

-drawRect:不應該有副作用。它只應根據視圖的當前狀態進行繪製,並應儘可能高效地進行。在-drawRect:內發送-setNeedsDisplay:消息將導致您每次通過主事件循環時重新繪製視圖。 – NSResponder

回答

4

我最初的直覺是嘗試調用[self setNeedsDisplay:YES];如果圖像不可用,在希望它會告訴可可(直到圖像繪製,再,再而三),即使調用的drawRect周圍再次下一次

這將是令人難以置信的低效率,有效。

隨時接下來的幾秒鐘內就可能會提供在那個時候我想提請它

所以,當這種情況發生,請致電[view setNeedsDisplay:YES]

如果您無法直接確定圖像何時可用,則必須進行輪詢。以合理的時間間隔設置重複的NSTimer - 比如0.25秒左右。 (這也是相當低效的,但至少它每秒只運行4次,而不是60次或更差。這是一個在兩個因素之間的權衡:您想要使用多少CPU和電池電量,以及圖像可用時間與顯示時間之間的延遲時間。)

my drawRect:method is除了我上面已經有的代碼之外沒有其他任何東西。

即使你什麼也不做的-drawRect:,可可仍然需要做很多幕後的工作 - 它需要管理髒rects,清除窗口的後備存儲的相應區域,它刷新到屏幕等等。這些都不是免費的。

+0

我認爲這是一個不好的解決方案。 WebView在發生事件時發送通知,並且應實現一個委託來捕獲這些事件並調用[view setNeedsDisplay:YES]。這裏不需要NSTimer! – thundersteele

+0

當然。這就是我所說的「當發生這種情況時」:如果有可以使用的委託方法或通知,那麼當然**使用它。如果沒有這樣的方法,你必須做一個效率較低的方法。 OP沒有具體說明是哪種情況。 –

+0

是的。這被標記爲可可,其中這樣的通知由WebView發送。否則,投票它當然是一個可行的解決方案。 – thundersteele

1

那麼,通常有一些委託方法被稱爲,當下載的東西完成。您應該實施該方法並在那裏致電setNeedsDisplay:YES