Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cocoa: Displaying an error after NSApp beginSheet results the main window hiding

I have broken this down into a very small project. Using the following code in the application delegate:

- (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 following action tied to button on the windows nib. (Note that the nib's window is also set to not be visible on launch).

- (IBAction) onClose: (id) sender
{
    [[NSApplication sharedApplication] endSheet: self.window
                                     returnCode: NSOKButton];

    [self.window orderOut: nil];    
} // End of onClose

What ends up happening is, once I the onClose runs, all of the windows disappear and I am left with nothing but the error dialog (the main window has disappeared). Error dialog with no main window

Is there something wrong with my code? Why does my main window go away?

NOTE: I know that I am not passing an error to the presentError method. I purposely left this null as I only had a short time to write the sample code. Passing an actual error results in the same behaviour.

Sample project is available here.

like image 993
Kyle Avatar asked May 23 '12 23:05

Kyle


2 Answers

Looks like you are still using the old api, try the new one

(deselect Always visible at launch 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 the UserLoginWindowController

- (IBAction)cancelButtonPressed:(id)sender {

    [[[self window] sheetParent] endSheet:[self window] returnCode:NSModalResponseCancel];

}
like image 55
Peter Lapisu Avatar answered Nov 11 '22 15:11

Peter Lapisu


You are using 2 methods to open your window, beginSheet:....., and runModalForWindow:. You only need one of those. If you want a sheet attached to your window, use the first method, if you want a stand alone window, use the second. Likewise, in your onClose method, you should use endSheet:returnCode: if you're closing a sheet (the argument for that method should be testingWindowController.window not self.window) , and stopModalWithCode: if you're closing a modal window, you shouldn't have both.

like image 1
rdelmar Avatar answered Nov 11 '22 17:11

rdelmar