Splash Screen in Cocoa Objective C

Splash Screen in Cocoa, Objective C

Written By : Debasis Das (26-Apr-2015)

Why do we need a Splash Screen?

Sometimes when loading the application instantly is not a practical option, one should give a Splash Screen with a Progress Indicator (Determinate or Indeterminate) to indicate there is work being done currently rather than giving users the rainbow spinner of death.

Some applications might need to connect to a remote database, get meta data information at the startup for initializing the application which might require than a couple of seconds and thus a splash screen

In this article we will create a simple Cocoa application that displays a Splash Screen while data is fetched in the background.

Cocoa Splash Screen

Borderless Cocoa Splash Screen

Cocoa Splash Screen Sample Code

App Delegate

//  AppDelegate.m
//  Created by Debasis Das on 4/25/15.
//  Copyright (c) 2015 Knowstack. All rights reserved.

#import "AppDelegate.h"
#import "SplashScreenWindowController.h"
@interface AppDelegate ()

@property (weak) IBOutlet NSWindow *window;
@property (nonatomic, strong) SplashScreenWindowController *splashWindowController;
@end

@implementation AppDelegate
- (void)applicationWillFinishLaunching:(NSNotification *)notification{

}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

    SplashScreenWindowController *sWC = [[SplashScreenWindowController alloc] init];
    
    [self setSplashWindowController:sWC];
    
    [self.splashWindowController showWindow:self];

    //Create a new Block Operation and add it to the Operation Queue
    NSOperationQueue *operationQueue = [NSOperationQueue new];
    
    NSBlockOperation *startUpCompletionOperation = [NSBlockOperation blockOperationWithBlock:^{
        //The startup Object has been loaded now close the splash screen
        //This the completion block operation
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
             NSLog(@"startUpCompletionOperation main thread? ANS - %@",[NSThread isMainThread]? @"YES":@"NO");
            [self.splashWindowController.window close];
            NSLog(@"Now you can open/show the application main screen");
        }];
    }];
    
    NSBlockOperation *startUpOperation = [NSBlockOperation blockOperationWithBlock:^{
        //This is the startup block operation
        [self loadStartUpObjects];
    }];
    
    [startUpCompletionOperation addDependency:startUpOperation];
    
    [operationQueue addOperation:startUpCompletionOperation];
    
    [operationQueue addOperation:startUpOperation];



}

-(void)loadStartUpObjects{
    
    NSLog(@"loadStartUpObjects running on main thread? ANS - %@",[NSThread isMainThread]? @"YES":@"NO");

    sleep(7); //Do some meaningful work here rather than sleeping
}

- (void)applicationWillTerminate:(NSNotification *)aNotification {
    // Insert code here to tear down your application
}
@end

Splash Display Window Controller

//  SplashScreenWindowController.h
#import <Cocoa/Cocoa.h>
@interface SplashScreenWindowController : NSWindowController
@end
//  SplashScreenWindowController.m

#import "SplashScreenWindowController.h"

@interface SplashScreenWindowController ()
@property (weak) IBOutlet NSProgressIndicator *progressIndicator;
@property (weak) IBOutlet NSTextField *applicationNameTextField;
@property (weak) IBOutlet NSTextField *detailInfoTextField;
@property (weak) IBOutlet NSImageView *imageView;

@end

@implementation SplashScreenWindowController

- (void)windowDidLoad
{
    [super windowDidLoad];
    
    //Read this from property file instead
    [self.applicationNameTextField setStringValue:@"Knowstack"];
    [self.detailInfoTextField setStringValue:@"More Info about application"];
    [self.imageView setImage:[NSImage imageNamed:@"NSApplicationIcon"]];
    [self.imageView setImageScaling:NSImageScaleProportionallyUpOrDown];
    //End reading from property file
    [self.progressIndicator startAnimation:self];
    //Below code is for positioning the Splash Screen at the Center of the Screen
    CGFloat xPos = NSWidth([[self.window screen] frame])/2 - NSWidth([self.window frame])/2;
    CGFloat yPos = NSHeight([[self.window screen] frame])/2 - NSHeight([self.window frame])/2;
    [self.window setFrame:NSMakeRect(xPos, yPos, NSWidth([self.window frame]), NSHeight([self.window frame])) display:YES];
}


-(NSString *)windowNibName{
    return NSStringFromClass(self.class);
}
@end

Splash Window

//  SplashWindow.h
#import <Cocoa/Cocoa.h>
@interface SplashWindow : NSWindow
@end
//  SplashWindow.m

#import "SplashWindow.h"
@implementation SplashWindow
- (id)initWithContentRect:(NSRect)contentRect
                styleMask:(NSUInteger)aStyle
                  backing:(NSBackingStoreType)bufferingType
                    defer:(BOOL)flag
{
    SplashWindow* window = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreNonretained defer:NO];

    window.appearance = [NSAppearance appearanceNamed:NSAppearanceNameVibrantDark];
    window.styleMask = window.styleMask | NSBorderlessWindowMask;
    window.titleVisibility = NSWindowTitleHidden;
    window.titlebarAppearsTransparent = YES;
    window.movableByWindowBackground = NO;
    window.level = NSModalPanelWindowLevel;
    window.alphaValue = 0.6;
    window.backgroundColor = [NSColor blackColor];
    window.hasShadow = YES;
    return window;
}
@end

You can download the code Cocoa Splash Screen

Posted in Cocoa, Objective C Tagged with: , , , , ,
2 comments on “Splash Screen in Cocoa Objective C
  1. arritjenof says:

    Hi,

    I appreciate your effort of documenting/outlining howto create a splash-screen, and you even motivate the reason why one would want to create one…

    Yet, i’d like to point-out that in virtually any instance where designers and/or developers did choose to display a splash-screen on application-startup, there is always a way to improve the design of the application and the splash could have been avoided.

    Really, who likes to be stuck, waiting for some animated window to finally go away and let you do your work? Noone!
    And i agree that having your application show the beachball-of-death is even worse, but this too can be prevented by improving on the overall design of the app.

    Apart from that, i also do have a problem with splash-screens because too often they’ve become way too important, and appearantly a significant amount time went into creating the splash alone… Sometimes it’s almost like the Splash-window wouldn’t be getting the attention it should, without its’ own Pre-Splash Splash-window… etc…

    Anyway, bottomlike: people don’t like to wait, and don’t want to be stuck watching stupid animating bars/gears/whatever.. And 99.9% of the time this is also completely unnecessary.

    • Debasis Das says:

      agreed, a splash screen is unnecessary, ideally an end user should never have to wait for the application to launch.
      However if the situation demands for some reason then this would be one way to show a splash screen 🙂

1 Pings/Trackbacks for "Splash Screen in Cocoa Objective C"
  1. […] you’re referring known splash screen. here‘s beginner-friendly tutorial on creating 1 in […]

Leave a Reply

Your email address will not be published. Required fields are marked *

*