Sheet opening unattached to window - cocoa

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.

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.

Modal session requires modal window

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];

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).
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.
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];
}
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.

Custom Sheet : can't click buttons

I used this source http://www.cats.rwth-aachen.de/library/programming/cocoa
to create my custom sheet.
I created a NSPanel object in existing .xib file and connected with IBOutlet
My source code:
.h
#interface MainDreamer : NSWindow <NSWindowDelegate>
{
...
NSPanel *newPanel;
}
...
#property (assign) IBOutlet NSPanel *newPanel;
.m
#dynamic newPanel;
...
//this method is wired with button on main window and calls a sheet
- (IBAction)callPanel:(id)sender
{
[NSApp beginSheet:newPanel
modalForWindow:[self window] modalDelegate:self
didEndSelector:#selector(myPanelDidEnd:returnCode:contextInfo:)
contextInfo: nil]; //(__bridge void *)[NSNumber numberWithFloat: 0]
}
//this method is wired with cancel and ok buttons on the panel
- (IBAction)endWorkPanel:(id)sender
{
[newPanel orderOut:self];
[NSApp endSheet:newPanel returnCode:([sender tag] == 9) ? NSOKButton : NSCancelButton];
}
//closing a sheet
- (void)myPanelDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
if (returnCode == NSCancelButton) return;
else{
return;
}
}
So callPanel works fine, sheet appears but I can't interact with controls on the sheet (with buttons). They don't react on a click (even visually).
Where the problem lies?
Heh, I forgot about
[newDreamPanel close];
in applicationDidFinishLaunching method. I wrote it because I wanted the panel to not appear when main window launches.
In fact, the Visible At Launch panel's property should be activated in IB. The close method works too, but side effect is that all controls become unable on the panel.

Resources