When developing iOS Apps it’s very rare to come up against a technical challenge that hasn’t already been solved and the solution shared on Stack Overflow or in Apple’s sample code in the iOS Dev Center. Unfortunately I haven’t experienced the same luxury with Mac OS X Development.
In a Mac App that I’m currently developing for a client I need to be able to create modally presented windows as sheets as described here in Apple’s Human Interface Guidelines.
Document Modal Dialogs or “Sheets” are instances of NSWindow. According to Apple’s documentation to present a custom NSWindow sheet we use the following code:
modalForWindow: window
modalDelegate: self
didEndSelector: @selector(didEndSheet:returnCode:contextInfo:)
contextInfo: nil];
Problem is beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo: was deprecated a few years ago and appears to no longer work in Yosemite and Mavericks 😕 With out-of-date documentation and all Googling resulting in out-of-date solutions to presenting custom modal windows, I went about figuring out the modern solution to this challenge!
The replacement for beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo: is to now call beginSheet:completionHandler: on the NSWindow that you want to present from, passing in reference to the instance of your custom NSWindow subclass.
I also discovered a few important steps that you need to implement when presenting sheets…
Step 1: Retain a reference to the NSWindow or NSWindowController that you are creating when presenting a sheet:
@property (strong) CustomModalWindowController *myCustomModalWindowController;
@end
@implementation MainWindowViewController
- (IBAction)didTapOpenButton:(id)sender {
self.myCustomModalWindowController = [[CustomModalWindowController alloc] initWithWindowNibName:@"CustomModalWindowController"];
[self.window beginSheet:self.myCustomModalWindowController.window completionHandler:^(NSModalResponse returnCode) {
}];
}
@end
Step 2: Deselect the Visible at Launch window attribute for your custom NSWindow or it’ll fail to present modally
Step 3: Call the window “sheetParent” in order to close the sheet and trigger the sheet completion block in the presentation code:
I’ve created a demo Xcode project that you can grab from my github repository to see this all in action:
Download source example from Github
Happy Coding!