Reputation: 1054
I have a Cocoa application built using Garbage Collection with a main window. This window provides a button which triggers an action on the window's controller when it is clicked as follows:
- (IBAction) buttonClick:(id)sender {
utilityWindowController = [[UtilityWindowController alloc] initWithWindowNibName:@"Utility"];
[utilityWindowController showWindow:sender];
}
This works fine, except that every time the button is clicked, a new window is opened, even if the one I got last click is still displayed. Ok - that's what I've asked it to do, but I want only one instance of this window at a time. So the behaviour I want is:
To try to get this behaviour, I tried this:
- (IBAction) buttonClick:(id)sender {
if (!utilityWindowController) {
utilityWindowController = [[UtilityWindowController alloc] initWithWindowNibName:@"Utility"];
}
[utilityWindowController showWindow:sender];
}
So that works better, because now my main window remembers the controller I created the first time I clicked the button and just shows the window if it already has one. However, it is basically reusing the same window, which causes another problem.
The utility window has a graphical display and starts a timer when it is first created. The utility window controller has a windowWillClose: method that disables the timer when the window is closed, since it's not useful to continue have the timer fire when the user can't see the display. However, when the user clicks the button in the main window to display the utility window for a second time, the window shows just fine, but the timer is not started again.
I cannot seem to find something like a windowWillShow: method that I could use to restart the timer.
The other way would be if the code above would be able to detect that the utility window was closed and recreate a new one so the awakeFromNib method would get called to start the timer. However, I don't know how I can do that.
A third method would of course be to proceed with the second version of the code above, but call a separate method that I will provide in the utility window controller that will start the timer if not already running.
What would be the best method of handling this type of thing? It seems like a fairly standard window management thing, but I haven't quite worked out the correct way of doing this in Cocoa.
Upvotes: 0
Views: 656
Reputation: 6932
Why don't you take the timer out of the awakeFromNib, and create it so you can reuse it. Make it a (@property). This way you can reuse it and invalidate it when needed. Funnily enough I just posted an example of doing that here
Upvotes: 1
Reputation: 96393
There isn't a delegate method or notification when a window is ordered in.
I would give the window controller another method that shows the window (if it isn't already up) and starts the timer (if it isn't already running), and have buttonClick:
simply send that message to the window controller.
The other way would be to use the original code, disable the button after creating the window controller, and re-enable the button (and destroy the window controller) when the window is closed. The disadvantage of this is that it leaves the user with no easy way to get back to the second window from the first (e.g., if they have a lot of windows on screen). If you leave the button enabled, you can have it order the window front again even if it's already up. That's why I'd go with my suggestion above.
Upvotes: 2
Reputation: 319
Try disabling the button while the other window is visible and re-enabling the button in the windowWillClose method. You could then also have the timer be reset by the buttonClick method or have it be disabled, as well as reset, in the windowWillClose method of the popup view.
[button setEnabled: NO]
Upvotes: 1