0

I have wrote an OSX storyboard application that has a splash screen. It is a NSWindow with NSWindowController, without subclassing, that have a SplashViewController that subclasses NSViewController.

Here is the code of SplashViewController:

- (void)viewDidLoad {
    [super viewDidLoad];

    _timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(timeOut) userInfo:nil repeats:NO];
}

- (void)timeOut
{
    [self performSegueWithIdentifier:@"main" sender:self];
}

- (void)prepareForSegue:(NSStoryboardSegue *)segue sender:(id)sender
{
    [_timer invalidate];
     _timer = nil;

    [self.view.window.windowController close];
}

This closes the window/window controller as expected.

The segue has show type and presents another NSWindowController which has MainViewController, subclass of NSViewController. When MainViewController opens a save dialog:

NSArray *a = [[NSApplication sharedApplication] windows];
NSLog(@"%ld", a.count);

NSSavePanel *savePanel = [NSSavePanel savePanel];
[savePanel setAllowedFileTypes:@[@"pdf"]];
[savePanel setDirectoryURL:[NSURL URLWithString:NSHomeDirectory()]];
[savePanel beginSheetModalForWindow:self.view.window completionHandler:nil];

an old splash window comes up (and "1" is printed). What the? I mean why it is showing up? And what NSSavePanel has to do with it?

Borzh
  • 5,069
  • 2
  • 48
  • 64

1 Answers1

0

Thanks to this answer (although partially unrelated) I managed to make it work.

Looks like there are several bugs when using storyboard (I am using XCode 6.3.1). In order to fix Them, you need to:

  • Select your initial window controller and uncheck "Is Initial Controller" (i.e. there is no initial controller set for the storyboard).

  • Your main window controller should be subclassed, even if subclass is empty.

  • Set Storyboard ID of your main window controller to Main (if you omit previous step, Storyboard ID be erased as soon as you leave storyboard, first bug).

  • In your AppDelegate.m add the following code:

    @property (strong, nonatomic) NSWindowController *mainWindowController;
    
    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {
        [NSApp activateIgnoringOtherApps:YES];
    
        NSStoryboard *storyboard = [NSStoryboard storyboardWithName:@"Main" bundle:nil];
        NSWindowController *main = [storyboard instantiateControllerWithIdentifier:@"Main"];
        [main showWindow:self];
        [main.window makeKeyAndOrderFront:self];
    
        // Important! Should be strong to retain instance. Second bug. 
        // If you don't do that, your window will open and close right away.
        _mainWindowController = main; 
    }
    
Community
  • 1
  • 1
Borzh
  • 5,069
  • 2
  • 48
  • 64