I am very much new to OSX development. Consider this as my first app. I want to display a sheet when a button is clicked on the main window. I am using Nib
Following is my code for .h file
#import <Foundation/Foundation.h>
#import "WebKit/Webkit.h"
@interface MainViewObject : NSObject
- (IBAction)accountButtonPressed:(id)sender;
- (IBAction)cancelSheetButtonPressed:(id)sender;
.m file as follows
#import "MainViewObject.h"
@implementation MainViewObject
- (IBAction)accountButtonPressed:(id)sender {
[NSApp beginSheet:self.accountSheet
modalForWindow:[mainWindowView window]
modalDelegate:nil
didEndSelector:nil
contextInfo:nil];
[NSApp runModalForWindow:self.accountSheet];
[NSApp endSheet:self.accountSheet];
[self.accountSheet orderOut:self];
}
- (IBAction)cancelSheetButtonPressed:(id)sender {
// Return to normal event handling
[NSApp endSheet:self.accountSheet];
// Hide the sheet
[self.accountSheet orderOut:sender];
}
When I run the app I get something like this:
https://i.stack.imgur.com/EKxQn.png
I am stuck and I have no idea what wrong in this. I am not able to get the sheet and the not able to even close the app. I have referred to some examples on internet.
Wow, looking at that, it's no surprise the screenshot looks as it is.
Let's walk through that one line at a time. When you click the Accounts button, you're doing 4 things immediately in succession:
You're telling the application to begin showing the sheet attached to your main window. This is OK, and is actually the only code you want in that
accountButtonPressed:
method.Right after beginning that sheet, you tell the application you want to also show that sheet all by itself (not attached to any windows but right in the middle of the screen), in an application-modal fashion, which blocks all other events from being processed in the application. In other words, this line doesn't really make sense. You either show a window as a sheet in a "document-modal" fashion (which only ties up the window that the sheet is attached to) or in an "application-modal" fashion, but not both at the same time. ;-)
Immediately after having just shown the sheet, you tell
NSApp
to stop showing the sheet. Now, you do want to do this eventually, but dismissing the sheet 0.0005 seconds after having just shown it will likely leave your users a little frustrated.You now tell the sheet to hide itself. This needs to be done from your
didEndSelector:
method, which brings us to the problems in your first method.-
This is good but read the documentation for
beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo:
and also the Sheet Programming Topics: Using Custom Sheets. (The Companion guides links at the top of Class Reference pages are especially helpful for learning how to use the APIs in the real world. They were extremely helpful when I was learning).Specifying
nil
for themodalDelegate:
means you don't have anything that's waiting to be notified about when the sheet has stopped being shown (this happens when you call[NSApp endSheet:sheet]
). You also haven't specified the@selector
you want called when the sheet is ended. A selector is kind of like a function, aka a "method".Your code should look something like this:
In this example, you click the Show Sheet button, and the sheet starts being shown attached to the main window. In the sheet, there is a Cancel and an OK button, which both call their respective methods. In each of these methods, you call
[NSApp endSheet:self.sheet]
. This tellsNSApp
that it should then call thesheetDidEnd:returnCode:contextInfo:
method on the object specified to be the modal delegate. InsheetDidEnd:returnCode:contextInfo:
you then tell the sheet to hide itself.EDIT:
Every
NSWindow
has a "Visible at launch" flag that can be set in Interface Builder. If this flag is set, the window will be visible at the time the nib file is loaded. If it isn't set, the window is hidden until you programmatically show it. Just edit the flag in the nib file like shown: