2011-12-22 231 views
0

我有一個使用垃圾收集與主窗口構建的Cocoa應用程序。該窗口提供了一個按鈕,當它被點擊如下窗口的控制器上觸發動作:打開和關閉窗口


- (IBAction) buttonClick:(id)sender { 
    utilityWindowController = [[UtilityWindowController alloc] initWithWindowNibName:@"Utility"]; 
    [utilityWindowController showWindow:sender]; 
} 

這每一個按鈕被點擊時工作正常,只是,打開一個新的窗口,即使一個我仍然顯示最後一次點擊。好的 - 這就是我要求它做的事情,但我一次只需要一個這個窗口的實例。所以我想要的行爲是:

  1. 如果窗口沒有顯示,創建一個新的並顯示它。
  2. 如果窗口正在顯示,或者什麼都不做,或者可能關注現有窗口(帶到前面等)。

,試圖讓這種行爲,我想這一點:


- (IBAction) buttonClick:(id)sender { 
    if (!utilityWindowController) { 
     utilityWindowController = [[UtilityWindowController alloc] initWithWindowNibName:@"Utility"]; 
    } 
    [utilityWindowController showWindow:sender]; 
} 

使作品更好,因爲現在我的主要窗口,記得我創造了我第一次點擊的按鈕控制器,只是顯示了窗口,如果它已經有一個。但是,它基本上是重複使用同一個窗口,這會導致另一個問題。

該實用程序窗口具有圖形顯示和首次創建時,它啓動定時器。實用程序窗口控制器有一個windowWillClose:方法,當窗口關閉時禁用定時器,因爲當用戶看不到顯示器時繼續定時器觸發沒有用。但是,當用戶單擊主窗口中的按鈕以再次顯示實用程序窗口時,窗口顯示正常,但計時器不會再次啓動。

我似乎無法找到像windowWillShow:我可以用它來重新啓動定時器方法。

另一種方法是,如果上面的代碼將能夠檢測到公用窗口被關閉並重新創建一個新的,因此awakeFromNib方法將被調用,以啓動定時器。但是,我不知道我該怎麼做。當然

第三種方法將與上述代碼的第二版本來進行,但調用一個單獨的方法,我將在實用程序窗口控制器如果尚未運行,將啓動定時器提供。

什麼是處理這類事情的最好方法是什麼?這看起來像一個相當標準的窗口管理的事情,但我還沒有完全搞清楚在Cocoa做這件事的正確方法。

回答

2

沒有一個委託方法或通知時是有序的窗口。

我想給窗口控制器,顯示窗口的另一種方法(如果它是不是已經啓動),並開始定時器(如果它尚未運行),並且只有buttonClick:只需將該消息發送到窗口控制器。

另一種方式是使用原始代碼,在創建窗口控制器後禁用按鈕,並在窗口關閉時重新啓用按鈕(並銷燬窗口控制器)。這樣做的缺點是它使用戶無法從第一個窗口回到第二個窗口(例如,如果他們在屏幕上有很多窗口)。如果您啓用按鈕,即使它已經打開,您也可以再次點擊窗口。這就是爲什麼我會採用我的建議。

+0

我決定採取這種方法,儘管其他答案也值得思考。從可用性的角度來看,禁用按鈕似乎是一個好主意,但是如果用戶已經打開了窗口,我希望該按鈕能夠將窗口置於最前面。 – OzBandit

1

嘗試停用按鈕,而另一個窗口是可見的和重新啓用所述windowWillClose方法的按鈕。然後,您也可以通過buttonClick方法重置計時器,或者在彈出視圖的windowWillClose方法中將其禁用以及重置。

[button setEnabled: NO] 
1

爲什麼不把定時器從awakeFromNib中取出來,然後創建它,以便重用它。把它做成(@property)。這樣您可以重用它並在需要時使其失效。有趣的是,我剛剛發佈了一個這樣做的例子:here