2015-07-03 32 views
0

現在我有兩個窗口。其中之一有一個NSView,它充當背景色,另一個有一個colorwell,用於更改共享實例中的顏色變量。NSView drawRect方法不工作?

我的節目排序的作品。我可以打開我的colorwell窗口並選擇一種顏色,但只有手動調整窗口大小時,背景顏色纔會更新。

我試圖讓過去的這個問題在後臺循環具有螺紋:

[self setNeedsDisplay:YES]; 
[self updateLayer]; 
[self display]; 

我不能完全肯定,那些3行是必要的,但我相信,他們正在重新調用我的drawRect方法。

我甚至把一個NSLog扔進drawRect方法來測試。我在控制檯看到它被再次調用。

這是我的drawRect方法:

- (void)drawRect:(NSRect)dirtyRect{ 

     [theDATA.main_frame_background_color setFill]; 
     [NSBezierPath fillRect:dirtyRect]; 

} 

theDATA.main_frame_background_color是從一個共享實例的NSColor。我肯定價值正在改變,因爲我調整窗口大小時,我的NSView更新。

我完全不知道爲什麼這不起作用。希望你能幫助。

+3

你不應該手動調用'display'方法。你嘗試過'NSRectFill'而不是'[NSBezierPath fillRect:]'?你有沒有檢查顏色是否真的改變了? –

+1

此外,如果您的視圖是分層支持的,您是否已將'layerContentsRedrawPolicy'屬性更改爲'NSViewLayerContentsRedrawOnSetNeedsDisplay'?默認值是'NSViewLayerContentsRedrawNever'。 –

+0

@ Sega-Zero非常感謝!您不想知道我花費了多長時間來解決此問題。設置'layerContentsRedrawPolicy'是一個開始。我發現'setNeedsDisplay'由於一些瘋狂的原因不是線程安全的,所以我使用了一個輔助方法(如我在這個問題的答案中所見)。 –

回答

0

我解決我的問題由於利用layerContentsRedrawPolicy的@世嘉-Zero的建議,並通過一些調查,我發現我不能直接調用setNeedsDisplay在一個線程,所以我用performSelectorOnMainThread

我的Thread類:

- (void)updateLOOP{ 
    while (true){  

      [self performSelectorOnMainThread: @selector(refreshClock) 
            withObject: nil 
           waitUntilDone: NO]; 

      [NSThread sleepForTimeInterval:.1]; 
     } 
    } 
} 

外部更新方法:

- (void) refreshClock{ 
    [self setNeedsDisplay:YES]; 
} 

現在一切正常,因爲它應該。 drawRect方法被調用而不必使用[self display]

+1

你真的需要這個線程嗎?你爲什麼不在價值變化上採用某種傾聽方式 - 通知中心,KVO甚至是一系列的塊。 –

0

首先,不要直接調用display方法。用setNeedsDisplay:標記髒區域,並在一段時間後重新繪製視圖。如果您的視圖是分層支持的,請注意layerContentsRedrawPolicy屬性,因爲它的默認值是NSViewLayerContentsRedrawNever。無法自動確定哪種策略最適合您的需求,因此應該手動設置此屬性。