Cocoa: displaying an error after starting NSSpp startSheet hides the main window
I broke it into a very small project. Using the following code in the application deletion:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { TestingWindowController * testingWindowController = [[TestingWindowController alloc] initWithWindowNibName: @"TestingWindowController"]; // Begin our sheet [NSApp beginSheet: testingWindowController.window modalForWindow: self.window modalDelegate: self didEndSelector: @selector(windowDidEnd:returnCode:contextInfo:) contextInfo: NULL]; } - (void)windowDidEnd:(id)alert returnCode:(NSInteger)returnCode contextInfo:(id) contextInfo { // If the user did not accept, then we really don't care what else they did! if (returnCode != NSOKButton) return; // We have had an error. Display it. [[NSApplication sharedApplication] presentError: nil modalForWindow: self.window delegate: nil didPresentSelector: nil contextInfo: NULL]; }
And the next action is tied to a button on windows windows. (Note that the nib window is also set so that it is not visible at startup).
- (IBAction) onClose: (id) sender { [[NSApplication sharedApplication] endSheet: self.window returnCode: NSOKButton]; [self.window orderOut: nil]; } // End of onClose
What happens when I run onClose
, all windows disappear and I leave only the error dialog (the main window has disappeared).
Is there something wrong with my code? Why is my main window leaving?
NOTE. I know that I am not passing an error to the presentError method. I intentionally left this zero since I only had a short time to write sample code. Passing the actual error leads to the same behavior.
A sample project is available here .
It looks like you are still using the old api, try the new one
(deselect Always displayed on startup for the UserLoginWindowController window)
- (IBAction)userButtonPressed:(id)sender { UserLoginWindowController * wc = [UserLoginWindowController new]; // we keep a reference, so the WC doesn't deallocate self.modalWindowController = wc; [[self window] beginSheet:[wc window] completionHandler:^(NSModalResponse returnCode) { self.modalWindowController = nil; }]; }
in UserLoginWindowController
- (IBAction)cancelButtonPressed:(id)sender { [[[self window] sheetParent] endSheet:[self window] returnCode:NSModalResponseCancel]; }
You use 2 methods to open your window, beginSheet: ..... and runModalForWindow :. You only need one of them. If you need a sheet attached to your window, use the first method, if you want a separate window, use the second. Similarly, in the onClose method, you should use endSheet: returnCode: if you close the sheet (the argument for this method should be checked by WindowController.window not self.window) and stopModalWithCode: if you close the modal window, you should not have both.