Problem using custom modal worksheet with Cocoa

My goal: to display my own sheet with a specific NSProgressIndicator, while the application runs through a long cycle. I want the sheet to be applied, not document-modal. User cannot reject modal sheet. They must wait for the application to complete the loop processing.

Problem: I cannot connect a user sheet to the window. It is displayed as a separate window, in which there is no window title bar (in the form of a sheet). In addition, the sheet does not release (does not close) when the loop ends.

I have 2 separate nib files for the sheet and the main application window, as well as 2 controller classes for each window.

Here's the pertinent information: Implementing a controller for a user sheet:

@implementation ProgressSheetController //subclass of NSPanel -(void)showProgressSheet:(NSWindow *)window { //progressPanel is an IBOutlet to the NSPanel if(!progressPanel) [NSBundle loadNibNamed:@"ProgressPanel" owner:self]; [NSApp beginSheet: progressPanel modalForWindow: window modalDelegate: nil didEndSelector: nil contextInfo: nil]; //modalSession is an instance variable modalSession = [NSApp beginModalSessionForWindow:progressPanel]; [NSApp runModalSession:modalSession]; } -(void)removeProgressSheet { [NSApp endModalSession:modalSession]; [NSApp endSheet:progressPanel]; [progressPanel orderOut:nil]; } //some other methods @end 

Implementation for the main application window. The testFiles method is an IBAction connected to the button.

 @implementation MainWindowViewController //subclass of NSObject -(IBAction)testFiles:(id)sender; { //filesToTest is a mutable array instance variable int count = [filesToTest count]; float progressIncrement = 100.0 / count; ProgressSheetController *modalProgressSheet = [[ProgressSheetController alloc] init]; [modalProgressSheet showProgressSheet:[NSApp mainWindow]]; int i, for(i=0; i<count; i++) { //do some stuff with the object at index i in the filesToTest array //this method I didn't show in ProgressSheetController.m but I think it self explanatory [modalProgressSheet incrementProgressBarBy:progressIncrement]; } //tear down the custom progress sheet [modalProgressSheet removeProgressSheet]; [modalProgressSheet release]; } @end 

One thought: am I subclassing correctly? Should I use NSWindowController? Thank you in advance for your help!

+4
source share
2 answers

Found this gem doing some search queries. The behavior of my NSPanel in Interface Builder was set to "Visible at Launch", which is used by default for new windows when using IB. What happened was as soon as the tip loaded, the window became visible until [NSApp beginSheet:...] . Therefore, having unchecked the "Visible at startup" checkbox, I solved the problem, and now the sheet appears, as I want, with the window.

+15
source
 @implementation ProgressSheetController //subclass of NSPanel -(void)showProgressSheet:(NSWindow *)window { //progressPanel is an IBOutlet to the NSPanel if(!progressPanel) [NSBundle loadNibNamed:@"ProgressPanel" owner:self]; 

So does your NSPanel own another NSPanel? If the second is a progress bar, what does the first show?

Should I [subclass] NSWindowController instead?

It sounds like that.

 modalSession = [NSApp beginModalSessionForWindow:progressPanel]; 

Why?

 [modalProgressSheet showProgressSheet:[NSApp mainWindow]]; 

Have you checked that there is a main window? mainWindow does not return the most interesting window; it returns the active window (perhaps, but not necessarily, also the key).

If mainWindow returns nil , this may be the cause of your problem.

 int i, for(i=0; i<count; i++) { //do some stuff with the object at index i in the filesToTest array 

First, int is the wrong type. You must use NSUInteger for NSArray indices.

Secondly, if you do not need an index for something else, you should use a quick enumeration .

+1
source

All Articles