打开和关闭窗口

问题描述:

我有一个使用垃圾收集与主窗口构建的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做这件事的正确方法。

没有一个委托方法或通知时是有序的窗口。

我想给窗口控制器,显示窗口的另一种方法(如果它是不是已经启动),并开始定时器(如果它尚未运行),并且只有buttonClick:只需将该消息发送到窗口控制器。

另一种方式是使用原始代码,在创建窗口控制器后禁用按钮,并在窗口关闭时重新启用按钮(并销毁窗口控制器)。这样做的缺点是它使用户无法从第一个窗口回到第二个窗口(例如,如果他们在屏幕上有很多窗口)。如果您启用按钮,即使它已经打开,您也可以再次点击窗口。这就是为什么我会采用我的建议。

+0

我决定采取这种方法,尽管其他答案也值得思考。从可用性的角度来看,禁用按钮似乎是一个好主意,但是如果用户已经打开了窗口,我希望该按钮能够将窗口置于最前面。 – OzBandit

尝试停用按钮,而另一个窗口是可见的和重新启用所述windowWillClose方法的按钮。然后,您也可以通过buttonClick方法重置计时器,或者在弹出视图的windowWillClose方法中将其禁用以及重置。

[button setEnabled: NO] 

为什么不把定时器从awakeFromNib中取出来,然后创建它,以便重用它。把它做成(@property)。这样您可以重用它并在需要时使其失效。有趣的是,我刚刚发布了一个这样做的例子:here