How to close current window after a new window showed - objective-c

In current NSWindowController, add a child window (mainViewController.window),then close current window,BUT when the method [self.window close] is called, the App terminated(not crash,because I can get the log message form method windowWillClose);
[self.window addChildWindow:mainViewController.window ordered:NSWindowAbove];
[self.window close];
What I want is : close current window when a new window showed.Is my way wrong?
=================================== UPDATE ====================================
Thanks #rdelmar, my mistake ,the App is not terminated,just all windows closed .
[self.window orderFront:mainViewController.window];
[self.window close];

If you want to close one window when you open another, then you shouldn't make that second window a child of the first. When you close a child window's parent window, the child will close also. You can just create a new window in code and then use orderFront or makeKeyAndOrderFront: to bring it on screen, then close your other window. You could also add another window in IB, and uncheck Visible At Launch so it will only show up when you call one of the methods I mentioned above.

Related

Cocoa HUD panel shows again after calling orderOut:

I'm using a NSPanel with HUD style to display some information.
There's a button inside the HUD panel, when the user clicks the button, I'll open a new window by calling:
[anotherWindowController showWindow:self];
[anotherWindowController.window makeKeyAndOrderFront];
And I want the panel disappear when the window shows, so I set the delegate of the main window, and in the windowDidResignMain callback, I called [hudPanel orderOut:nil].
The HUD panel did disappear (I can see it), but right after it closed, it reopens.
I've checked all possible orderFront: code, and none of them get called. So my hands are really tied. Is this a system level behaviour? Can anyone guide me through this?
EDIT:
I forgot to mention that, the button resides in a NSPopover. So, basically, there's a NSButton in the HUD panel. When user clicks the button, a NSPopover will show up, inside which, there's the button to bring up the new window.
Big thanks!
I had the problem. The following solved it:
[NSApp endSheet:yourPanel];
[yourPanel orderOut:self];
Use
[hudPanel performClose:nil]
(in Swift I have to use self instead of nil). I had a problem using orderOut with a popover and it was solved by using the above method.
Please add [hudPanel close] after [hudPanel orderOut:nil]
swift: hudPanel.close()
from the apple docs:
If the window is the key or main window, the window object immediately behind it is made key or main in its place. Calling orderOut(_:) causes the window to be removed from the screen, but does not cause it to be released. See the close() method for information on when a window is released.
Sometimes the window reappears during window controller inner logic, I think. I have an issue when long pressing keyboard button kills window, but shot keyDown event only hides it on the split second. After using close all goes smoothly.

How to wait for window to close inside a framework?

I have to create a function into a framework which opens a window with a radio group and a button on it. When I click the button, the function should print out which radio was selected. I´m using a NSWindowController with xib file to show the Form.
The problem is, that the code continues running after showing the window.
So I tried a while loop with a property in my window which is set when I click the button.
But it does not work because I think the window is running in the same thread.
MyWindowController windowController = [[MyWindowController alloc initWithWindowNibName:#"MyWindow"];
[windowController showWindow:self];
while([windowController buttonClicked] == 0);
NSLog("Radio %# is selected!", [windowController selectedRadio]);
Do you have any idea how to wait for the window to close and than read out the data?
I hope you can help me.
You can add your self as delegate tao the window and listen for windowWillClosenotifications. That way you get informed when the windows is getting closed.
Note that you are not "waiting" on the window toi close, that wouldn't work without blocking the runloop, but you just sit idle until the delegate method is called. Also note that the window controller should be automatically a delegate to the window and thus could also be used for this.

Disabling Window Behind

These days, I develop iPad applications. Since I've run out of subjects to work on, I'm working on a simple OS X application to see how far I can go.
Anyway, what I want to do is show a Preferences window (PrefWindowController). It has a separate xib (PrefWindowController.xib) from MainMenu.xib. When it appears, I want the main window to go behind it. The following is what I have.
// AppDelegate.m
- (void)preferencesClicked:(id)sender {
if (!preferencesWindow) {
preferencesWindow = [[PrefWindowController alloc] initWithWindowNibName:#"PrefWindowController"];
}
[preferencesWindow showWindow:self];
}
// PrefWindowController.m
- (void)windowDidLoad {
[super windowDidLoad];
[NSApp runModalForWindow:self.window];
NSLog(#"Hello!?");
}
- (IBAction)closeClicked:(id)sender {
[NSApp stopModal];
[self close];
}
So I've learnt that I can use runModalForWindow to put the current window on top of the main window. The problem that I have is that this preferences window will reopen when I click on the close button (closeClicked). If I click on it again, it will close. If I open Preferences and click on the same button, it won't reopen. An interesting thing is that the application won't read NSLog(#"Hello!?") when the Preferences window first opens. It does when I clicked on the close button. Do you know what I'm doing wrong?
Thank you for your help.
Modal doesn't mean display on top. Modal means stop the user interacting with anything else other than this. It does this by creating a new run loop, which means that anything after runModelForWindow won't happen till after the modal window is closed. Exactly what you are seeing with the NSLog.
You probably don't want to use a modal window for preferences. The convention for OSX is that the main app window stays active when a preferences window is open.
If you just want to bring the window to the front, and don't care if the user later clicks on the main window to bring it to the front, then use -makeKeyAndOrderFront on the window you have. If on the other hand you want this preferences window to always be in front, then make it an NSPanel rather than an NSWindow.

NSWindow - show new window that will always stay on top of current window

I want my NSWindow to show new window(s) that will always be on top of current window. they should NOT be on top of other windows.
In addition, they should not move when the original window moves.
How can i do that?
Use NSWindow's addChildWindow:ordered: or setParentWindow: method to add the other window as a child of the first window. That window will follow the first window around. See the NSWindow Class Reference.
You can set window level to NSFloatingWindowLevel so it always be on top.
To prevent window from covering other applications you can set its level to NSNormalWindowLevel or you can hide it at all. Try to use applicationWillResignActive: method (NSApplicationDelegate Protocol) to remove your window from top. To catch the moment when you shoud bring your window back on top use applicationWillBecomeActive: method.
This worked for me, hope that will be helpful
[self.window makeKeyAndOrderFront:nil];
[self.window setLevel:NSStatusWindowLevel];

set NSWindow focused

I have an app winth one window and one panel, attached to this window.
steps:
deactivate my app (app opened, but without the focus)
click on a button on panel (panel is focused now, but main window is not)
How to set focus to the main window (parent window) from the panel?
Swift 5 version of #BUDDAx2 answer:
NSApplication.shared.activate(ignoringOtherApps: true)
It is not clear what you mean by focus, and whether what you call main window is a main window as defined in Cocoa. Assuming it is a Cocoa main window and focus is the same as key status,
[[NSApp mainWindow] makeKeyWindow];
or
[[NSApp mainWindow] makeKeyAndOrderFront:self];
If it is not a Cocoa main window, you need to have a reference to it and send it -makeKeyWindow or -makeKeyAndOrderFront:.