17 Comments

Summary:

All too often an iPhone application’s launch sequence is an overlooked detail. The most common approach is to misuse the provided Default.png file as a splash screen. This detailing of an application is more than a little challenging if you want to get it right.

All too often an iPhone application’s launch sequence is an overlooked detail. The most common approach is to misuse the provided Default.png file as a splash screen. As it turns out, this detailing of an application is more than a little challenging if you want to get it right and stay within Apple’s guidelines.

The key to a smooth and professional looking launch sequence starts with knowing exactly where the application will land at startup. Some applications start at exactly the same place each and every successive launch, others attempt to preserve the application’s state and launch into the screen where the user last used the application. Keeping this in mind can change the strategy of how the launch sequence is implemented. This includes screen orientation as well as how and even if the status bar it to be displayed.

One may witness flickering of the status bar from blue, to black or from black to blue during the launch sequence. This is mainly due to the fact that there are two places to change the behavior of the status bar. One is hidden in the info.plist file, and the other is typically via code in the Application Delegate’s applicationDidFinishLaunching method. The info.plist configuration is used before the main window is loaded, and the code in the Application Delegate is used during the launching of the main window. The reason one may want to utilize both styles is to take advantage of a full screen splash page, and then enable the appropriate looking status bar once the application has finished loading.

For the purpose of this example application, we will assume that the user state is preserved between executions, and we do not know exactly what the screen will look like when the user enters the application. We will therefore be implementing a full-screen splash view that will have the status bar hidden during the launch sequence. Once the splash view has disappeared, a black opaque status bar will be utilized throughout the application. It is also assumed that the application will launch in portrait mode, and that the first screen the user will see will also be in portrait mode.

Editing the Configuration File

The first order of business is to take care of the status bar. In Xcode, locate the info.plist file for the project. To add an additional property to the plist file, simply select one of the entries and click on the plus tab that appears to the right and select Status Bar Style from the drop down list:

Edit Projects plist File

Edit Projects plist File

There are only three different styles to choose from. Try each style out to see which one fits the needs of the application being developed. For this example we will set the style to UIStatusBarStyleDefault.

UIStatusBarStyles:
UIStatusBarStyleDefault — Gray (the default)
UIStatusBarStyleBlackTranslucent — Transparent black (specifically, black with an alpha of 0.5)
UIStatusBarStyleBlackOpaque — Opaque black

If on the other hand the desire is to hide the status bar when the application launches, then yet another property needs to be set. In this case, add the “Status Bar is initially hidden” property to the plist file and be sure to check the box next to the property.

Editing the Application Delegate code

So now that the status bar style is set, and initially hidden, how does one get the status bar to display again? You can actually turn the status bar on and off programmatically via code. This is particularly handy when the need arises to display a full screen view, such as the splash screen this application is utilizing. In the applicationDidFinishLaunching method of the Application’s designated AppDelegate class, add the following line of code to make the status bar visible again:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    // Override point for customization after app launch
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
    [[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES];
}

Adding a Default.png Image

Surprisingly, the size of this file is not as important as the naming convention of the file. Default.png is a case sensitive PNG file. The image should be 480×320 according to Apple. Following Apple’s conventions, this image should look like the view that the user will see when the application has launched, and not the actual splash screen.

Xcode provides a mechanism to create a Default.png file from an attached device running the application. From the Organizer window, select the device, click on screenshots and click capture. To make that screenshot your application’s default image, click Save As Default Image. Even though the image that is created includes the status bar as it looked when the screen shot was captured, the iPhone OS replaces it with the current status bar when your application launches. Just to be clear, this is not a splash screen…not yet.

Long Launch Sequences to Varying Views

So far, this is what most applications will implement if they implement any sort of controlled visual experience when the application launches. If you follow Apple’s guidelines, and the image you produce is the first screen that the user will see, all is good. Except, what if the launch sequence is not as fast as the user expects? What if the application preserves state and lands on a different view based on the users last know state? Then this technique is not up to the task.

Photoshop a branded image representing the application and save it as a PNG image sized at 480×320. Do not include a status bar of any kind in the image file being created. Add this image file to the project. Now the application sort of has a splash screen, through a misused implementation of the Default.png file. To correct this, simply add an image view as a property to the App Delegates header and create it as follows:

    splashView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    splashView.image = [UIImage imageNamed:@"Default.png"];
    [window addSubview:splashView];
    [window bringSubviewToFront:splashView];

At this point, the image view is utilizing the exact same image file that was created in Photoshop. There’s no chance of the initial view being different than the Default.png file at this point. The one remaining problem is the timing of when to remove the image view from the subview. This can be handled in one of two ways…

Controlling the Duration of the Splash Screen

The first option is for those with quick startup times that just want a splash screen. In this situation, create a method to remove and release the splash view, then calling that method via a timed perform selector call as follows:

    [self performSelector:@selector(removeSplash) withObject:nil afterDelay:1.5];

The removeSplash method does just that, removes the image view from the subview and releases the object.

    -(void)removeSplash;
    {
      [splashView removeFromSuperview];
      [splashView release];
    }

The second method uses the same remove splash method, but relies on the built in event management to trigger when the method gets called.

    [[NSNotificationCenter defaultCenter] addObserver:self
          selector:@selector(saveClaim:)
          name:@"RemoveSplashScreen"
          object:nil];

Now all that needs to be done is to post the notification from anywhere. This technique is particularly useful if the reason that the launch sequence is taking a long time has nothing to do with code that was implemented in the App Delegate.

    [[NSNotificationCenter defaultCenter]
          postNotificationName: @"RemoveSplashScreen"
          object: nil];

This technique can be employed from anywhere within the application. Removing the observer after the fact may avoid crashes if there is an opportunity for this notification to be fired multiple times. Releasing an object when no object it there to be released can lead to troublesome crashes to track down. The quick and dirty is to use the delay on the performSelector call.

Conclusion

And there it is, a splash screen that conforms to Apple’s guidelines. No hidden APIs, no hacks, no special sauce. A simple, straight forward approach to making the initial interaction with the user as pleasant as possible.

References:

  1. In your removeSplash method, I noticed that you released splashView there instead of releasing it immediately after adding it as a subview to window. Isn’t the convention to release at immediately after adding it as a subview, since at the point to superview retains it?

    Share
  2. [...] iPhone Dev Sessions: Making a Splash Screen Mac Love [...]

    Share
  3. That was because I also removed it from the superview in the removeSplash method, and needed a reference to it. In other versions of this example, there are additional views that are animated. The risk would be that the removeSplash method never gets evoked.

    Share
  4. Thanks. This is helpful.

    Share
  5. Thanks for the explanation in this interesting article. I’m still learning iPhone development. Can I download a some project somewhere ?

    Share
  6. [...] iPhone Dev Sessions: Making a Splash Screen Mac Love [...]

    Share
  7. [...] iPhone Dev Sessions: Making a Splash Screen (tags: iphone objective-c programming code development tutorials) [...]

    Share
  8. [...] is the original: iPhone Dev Sessions: Making a Splash Screen addthis_url = [...]

    Share
  9. [...] iPhone Dev Sessions: Making a Splash Screen Mac Love [...]

    Share
  10. Thanks Geoffrey,

    best example I have found so far about creating a splash that keeps inline with their guidelines.

    Agreed with Frank, do you have an example to share? i tried to implement, but think i didn’t place the code correctly.

    Thanks again…….!

    Share

Comments have been disabled for this post