How to open NSSheet in Mavericks?

At Mavericks, the NSSheets open and close methods have changed. And to make it tougher, the Release Notes do not match the current documentation (see below).

I am trying to do this:

MainSheetController (NSWindowController):

-(IBAction)callSheet:(id)sender {
    [sheetController openSheet];
}

SheetController (NSObject):

 (void)openSheet {  
    [[NSBundle mainBundle] loadNibNamed:sheetName owner:self topLevelObjects:nil];
    NSLog(@"1");
    [self.mainWindowController.window beginSheet:self.sheet completionHandler:nil];
    NSLog(@"2");    
}

I get up to 2, with no errors or warnings, but no sheet.

Current documentation:

#if NS_BLOCKS_AVAILABLE
- (void)beginSheet:(NSWindow *)sheetWindow completionHandler:(void (^)(NSModalResponse returnCode))handler NS_AVAILABLE_MAC(10_9);
- (void)beginCriticalSheet:(NSWindow *)sheetWindow completionHandler:(void (^)(NSModalResponse returnCode))handler NS_AVAILABLE_MAC(10_9);
#endif
+3
source share
3 answers

I figured out how to do it. Hope it's ok to post ..

mainwindow.h

@interface MainWindowController : NSWindowController {
    NSString *sheetName;
    IBOutlet NSWindow *sheet;
    id result1;
    id result2;
    ...
    id resultn;
}

@property (strong) NSString *sheetName;
@property (strong, nonatomic) IBOutlet NSWindow *sheet;

-(IBAction)callSheet0:(id)sender;
-(IBAction)callSheet1:(id)sender;
-(IBAction)callSheetn:(id)sender;

- (void)openSheet;
- (IBAction)save:(id)sender;
- (IBAction)cancel:(id)sender;

MainWindow.m

- (void)windowDidLoad
{
    NSLog(@"%s", __FUNCTION__);
    [super windowDidLoad];
    sheetName = [[NSString alloc] init];
}


-(IBAction)callSheet0:(id)sender {
    NSLog(@"%s", __FUNCTION__);
    sheetName = @"Sheet0";
    [self openSheet];
}
....

-(IBAction)callSheetn:(id)sender {
    NSLog(@"%s", __FUNCTION__);
    sheetName = @"Sheetn";
    [self openSheet];


- (void)openSheet {
    NSLog(@"%s", __FUNCTION__);
    NSLog(@"sheetName: %@",sheetName );
    [[NSBundle mainBundle] loadNibNamed:sheetName owner:self topLevelObjects:nil];
    [self.window beginSheet:self.sheet completionHandler:nil];

}

- (void)save:(NSButton*)sender {

    switch ([sender tag]) {
        case 0:
            [self doSave1];
            result = @"1";
            break;

        case 1:
            [self doSave2];
            result = @"2";
            break;

        case n:
            [self doSaven];
            result = @"x";
            break;
    }
    [self endSheet:self.sheet returnCode:result];
}


- (IBAction)cancel:(id)sender {
    NSLog(@"%s", __FUNCTION__);
    result = @"0";
    [self endSheet:self.sheet returnCode:result];
    // returnCode is optional
}

//endSheet:(NSWindow *)sheetWindow  {
- (void)endSheet:(NSWindow *)sheetWindow returnCode:returnCode {
    //NSLog(@"%s", __FUNCTION__);
    [sheetWindow orderOut:self];

}

- (void)save:(NSButton*)sender {

    switch ([sender tag]) {
        case 0:
            [self doSave1];
            result = @"1";
            break;

            case n:
            [self doSave3];
            result = @"3";
            break;
    }
    [self endSheet:self.sheet returnCode:result];
}

Using this method, new in 10.9, I don’t need a special sheet controller, and the control remains a local quote.

+1
- (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;
    }];

}

UserLoginWindowController

- (IBAction)cancelButtonPressed:(id)sender {

    [[[self window] sheetParent] endSheet:[self window] returnCode:NSModalResponseCancel];

}
+10
- (IBAction)showSheet:(id)sender
{
    if (_windowController == nil)
    {
        _windowController = [MyWindowController new];
    }

    [[self window] beginSheet:[_windowController window] completionHandler:^(NSModalResponse returnCode)
    {
    }];
}

// And inside your MyWindowController class:

- (id)init
{
    self = [super initWithWindowNibName:@"MyWindowNibName"]; // TODO: Change the name of your NIB
    return self;
}

In your nib file, make sure the "Visible At Launch" flag is not intended for the window.

+5
source

All Articles