7

I am showing a sheet within my main window. I present the sheet using this code:

AddContactWindowController *addContact = [[AddContactWindowController alloc] initWithWindowNibName:@"AddContactWindow"];
addContact.currentViewController = myView;
self.addWindowController = addContact;

[self.view.window beginSheet: addContact.window completionHandler:^(NSModalResponse returnCode) {
    NSLog(@"completionHandler called");
}];

AddContactWindowController is a NSWindowController subclass. It has a view controller within it. Inside the view is a "close" button which invokes this:

[[[self view] window] close];

This does close the window, but the completionHandler from beginSheet is not invoked. This causes me problems down the road.

Is there any particular way we should close the NSWindow sheet for the completion handler to be successfully called? I've also tried [[[self view] window] orderOut:self] but that doesn't work either.

Thanks.

Z S
  • 7,039
  • 12
  • 53
  • 105

2 Answers2

7

You will want to call -endSheet:returnCode: on your window, rather than just ordering it out.

sudo rm -rf
  • 29,408
  • 19
  • 102
  • 161
  • From within the presented sheet, I've tried this: `[self.view.window.sheetParent endSheet: self.view.window]` ... I've also paired it with `self.view.window close`. I get the same result; the window goes away from the main window, but completion handler is still not called. – Z S Aug 01 '14 at 06:10
  • 1
    Turns out, I had to call them in the opposite order: first the `[sheetParent endSheet: self.view.window]` and then the `[self.view.window close]`. Then I get the completion handler called in between these two calls. – Z S Aug 01 '14 at 06:18
  • Great, glad you got it sorted out. For what it's worth, you shouldn't need to close the window manually. Last time I checked, it is dismissed for you after the completion handler is called, and you don't need to order it out yourself. But I might be wrong about that. – sudo rm -rf Aug 01 '14 at 06:20
  • In my case, I definitely need to call `close`; without it, the sheet stays on top of my window for some reason. – Z S Aug 01 '14 at 06:54
  • If you close the modal sheet with escape then you don't have a chance to invoke one of the above. The completion handler isn't called in that case too. This looks like a bug. – qwerty_so Nov 23 '14 at 16:35
2

You must properly finish the modal session.

I used to call - (void)performClose:(id)sender and stop the modal session in the delegate method.

- (void)windowWillClose:(NSNotification *)notification {
    [NSApp stopModal];
}

But for a sheet, endSheet looks more appropriate.

self.addWindowController = addContact;

[self.view.window beginSheet:self.addWindowController.window];
...
...
[self.view.window endSheet:self.addWindowController.window];

self.addWindowController = nil
9dan
  • 4,222
  • 2
  • 29
  • 44
  • Thanks. @sudo pointed me to the same direction and I got it working, so I'll mark his answer correct. – Z S Aug 01 '14 at 06:20