Modal session requires modal window - cocoa

I'm trying to open a window like a sheet so that it appears down below the toolbar. I've used the O'Reilly tutorial to do this. However, I can get past this error: Modal session requires modal window.
The window loads as a window if I have "Visible At Launch" checked.
Whether it is checked or not I get the "Modal session requires modal window" error.
I have a Window.xib, ProgressModal.xib.
In the Window implementation file I use:
-(IBAction)loadProgress:(id)sender{
[self progressStatus:progressWindow];
}
- (void)progressStatus:(NSWindow *)window {
[NSApp beginSheet: window
modalForWindow: mainWindow
modalDelegate: nil
didEndSelector: nil
contextInfo: nil];
[NSApp runModalForWindow: window];
[NSApp endSheet: window];
[window orderOut: self];
}
- (IBAction)cancelProgressScrollView:(id)sender {
[NSApp stopModal];
}
I may have the ProgressModal.xib setup wrong. I have an NSObject in it that has "Window" as its class. All the connections are made through that.
But again, it loads the window just won't load it as a modal.
Any ideas?

Put the following in the first line of your progressStatus method:
NSLog(#"%#", window);
If you see the log output is null, that's the reason why.
Steps to create a modal sheet using XIB:
Drag a panel to your MainMenu.xib
Add #property (assign) IBOutlet NSPanel *sheetPanel; in your AppDelegate.h file
#synthesize sheetPanel = _sheetPanel; in the AppDelegate.m file
Link a New Referencing Outlet of the panel in the MainMenu.xib created in the step 1 to the sheetPanel property created in step 2.
Using following code to show the modal sheet:
[NSApp beginSheet:_sheetPanel
modalForWindow:_mainWindow
modalDelegate:self
didEndSelector:#selector(didEndSheet:returnCode:contextInfo:)
contextInfo:nil];

As I stated above, I dragged an object over in the progressModal window and made my connections through that. What I should have done was made the File's owner my Window class. Changing that fixed the problem.
I got this from http://www.youtube.com/watch?v=QBkO6TD-fWA

Edit: I assumed you wanted a modal window. If you want a sheet, don't use runModalForWindow: at all.
Try this:
[NSApp beginSheet: window
modalForWindow: mainWindow
modalDelegate: nil
didEndSelector: nil
contextInfo: nil];
It's a good idea to define a callback just in case you need it though; e.g.
[NSApp beginSheet: window
modalForWindow: mainWindow
modalDelegate: self
didEndSelector: #selector(sheetDidEnd:returnCode:contextInfo:)
contextInfo: nil];

Related

NSWindow beginSheet completionHandler not called

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.
You will want to call -endSheet:returnCode: on your window, rather than just ordering it out.
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

cocoa sheet on document-based app

I got a dialog instead of sheet.It worked when the app was not document-based.
Now it doesn't work.
- (IBAction) showSheet:(NSWindow*)window
{
// User has asked to see the dialog. Display it.
NSLog(#"%#", self.contragentsSheet);
if (!_contragentsSheet)
[NSBundle loadNibNamed: #"contragentsSheet" owner: self];
[NSApp beginSheet:self.contragentsSheet
modalForWindow: [[NSApp delegate]window]
//modalForWindow: window
modalDelegate: self
didEndSelector: NULL
contextInfo: NULL];
//[contragentSearch becomeFirstResponder];
//NSLog ( #"Sheet is launched");
NSLog(#"%#", [[NSApp delegate]window]);
}
Don't use [[NSApp delegate] window] you need to explicitly tell the method which window you want to display the sheet on. Document based Apps can have many windows and a sheet is attached to one.

Sheet opening unattached to window

I have a problem with a sheet that when opened for the first time, will open unattached to the window. After dismissing it, then the sheet works as it should.
Here is the code that I am starting the sheet with:
- (IBAction)addButtonAction:(id)sender {
assert ([editorController window]);
assert (window);
[NSApp beginSheet: [editorController window]
modalForWindow: window
modalDelegate: editorController
didEndSelector: #selector(didEndSheet:returnCode:contextInfo:)
contextInfo: nil];
}
The variables 'window' and 'editorController' are initialized in the application delegate header file as #private.
The 'didEndSelector' is defined in the 'editorController' code file and is called when the window is closed.
The code for the 'didEndSelector' is as follows:
- (void)didEndSheet:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
[sheet orderOut:self];
}
The window is cancelled with a call to selector 'cancelButtonAction' which is as follows:
- (IBAction)cancelButtonAction:(id)sender {
[NSApp endSheet:self.window];
}
Any thoughts would be appreciated.
Make sure the "visible at launch" option on the NSWindow in the xib file isn't turned on.

How show sheet loaded from xib? (MacOSx)

I have a xib file with only an NSPanel in it, I'm trying to show this panel as modal sheet (with beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo:). The file's owner for this xib is a controller class "MyController" which has the IBOutlet to the NSPanel.
What I am looking for is something like:
...
MyController *controller = [[MyController alloc] init];
[NSApp beginSheet:controller.panel modalForWindow:[NSApp mainWindow] modalDelegate:controller didEndSelector:nil contextInfo:nil];
...
Question:
Must MyController inherit from NSWindowController or NSObject?. I tried NSWindowController and initWithWindowNibName: but the outlet to NSPanel always is nil.
Thanks
I resolve it. You must deactivate almost all the properties of the window object (in the IB) that you are using for the sheet. I add the following method to my controller to show the sheet:
- (void)showInWindow:(NSWindow *)mainWindow {
if (!panelSheet)
[NSBundle loadNibNamed:#"XibName" owner:self];
[NSApp beginSheet:panelSheet modalForWindow:mainWindow modalDelegate:nil didEndSelector:nil contextInfo:nil];
[NSApp runModalForWindow:panelSheet]; //This call blocks the execution until [NSApp stopModal] is called
[NSApp endSheet:panelSheet];
[panelSheet orderOut:self];
}
panelSheet is an IBOutlet to the sheet window.
Thanks Jon Hess and JWWalker for your help

How do stop panels from becomming key window on launch?

I have a xib file with a main window and a panel. On awakeFromNib I try to orderFront the main window, but the panel keeps being key window.
- (void)awakeFromNib {
[inspectionPanelOutlet orderBack:self];
[inspectionPanelOutlet orderWindow:NSWindowBelow relativeTo:0];
[window makeKeyAndOrderFront:self];
}
This code has no effect.
Are you sure awakeFromNib is called (add an NSLog message and see if it fires)? If it is called you might want to try:
[self makeMainWindow];
or
[self makeKeyWindow];

Resources