In March I created a splashView class which makes it easy to create a splash screen in your iPhone program. Since then, it's achieved a lot of attention,causing me to put together a slightly revised version of the class, along with some hopefully more straightforward instructions on how to use the class.
They follow, below.
The Code
You can download the new splashView class here: Download SplashView 1.1.
I've also put together a sample project with the splashView already in place. You can find that here: Download NavSample. It builds the splashView into the navigation template. That was chosen pretty arbitrarily; you could put the splashView into any other template, as you see fit.
Below is what you need to know about the class. Most of this, I've copied straight from my earlier article, but updated to correctly describe the usage for the current version of splashView. I'll talk about the changes a bit later.
The Methods
There are just two methods intended for external use.
initWithImage:
- (id)initWithImage:(UIImage *)screenImage;
Give the SplashView a 320x460 image that will be used to fill the screen.
startSplash
- (void)startSplash;
Once you've set all your properties, run this to start the timer of the SplashView going.
The Properties
I filled SplashView with properties, so that you can use it in whatever manner you see fit. Here's a run-down of all of the ones intended to be user accessible:
animation (enum). What sort of animation to show when the SplashView disappears. Options are SplashViewAnimationNone, SplashViewAnimationSlideLeft, and SplashViewAnimationFade. Default is SplashViewAnimationNone (no animation).
animationDelay (NSTimeInterval). How long the animation should run. Default is 1s.
delay (NSTimeInterval). How long the SplashView displays before it disappears. Default is 2s.
delegate (id). What object will listen for splashView's optional delegate protocol.
touchAllowed (BOOL). Whether a user can touch the splash screen to immediately make it disappear (or start animating away). Default is NO.
The Protocol
Sometimes you'll want to know when your splashView closes down. That's what the protocol allows. You just need to set your responding object as the splashView's delegate and have it respond to the splashViewDelegate protocol. This will give you access to one protocol method:
splashIsDone
- (void)splashIsDone;
If you want a reminder on how protocols are used, you should consult iPhone in Action p.179. If you want a reminder on how new protocols are created, you should read Create Delegate Protocols for the iPhone, an earlier article.
Using the Class
If you want to use this class in your program, you can do so under a simple Creative Commons license, which basically says that you'll leave our credits in the comments of the class. Other than that, it's free for your use.
Here's the steps to get it running:
- Copy the splashView.h and splashView.m files into your program using "Add > Existing Files". When you do so, be sure to check the box that says to physically copy them.
- Add the QuartzCore framework to your project.
- Decide which file you're going to activate the splashView from. I suggest the app delegate as the most obvious location for this sort of big-picture content, but I think the splashView is now set up correctly so that you can run it from anywhere.
- #import "splashView.h" into the appropriate file.
- Create your 320x460 PNG. I suggest naming it Default.png. Copy it into your program using "Add > Existing Files", again being sure to check the box so that it gets physically copied.
- Code the splashView startup.
Coding the splashView startup just requires the use of the init and startSplash methods previously noted. Here's a minimalist example:
splashView *mySplash = [[splashView alloc] initWithImage:
[UIImage imageNamed:@"Default.png"]];
[mySplash startSplash];
[mySplash release];
For a less minimalist example, you'd set some of the properties before running startSplash. If anything isn't clear about how to put these pieces together, you should take a look at the navSample class, linked above.
About Default.png: So why did I suggest using Default.png for the filename? It's because the iPhone will automatically show a file by that name while a program is being loaded. It doesn't do any of the fancy transitions that this class does, nor does it offer any guarantees about how long it'll stay up, but other than that it could be used as a low-budget splash screen (though the purpose was actually to imply that the program was loading faster than it really was).
If you name your image Default.png, then you get the best of both worlds. The PNG will show while the program loads, then the splashView will simultaneously start with your same image, which will eventually transition out via whatever animation method you defined. If you do this, you probably want to tune down the delay once you test it out on a real iPhone, so that users don't feel like they're looking at your splash screen for tool long.
The Changes
I'm going to talk a little bit about the code here, and you might want to first read part two of my original article series, which covers the header file and part three, which covers the source code file. Not only will this give you better context for this update, but it'll also show you the techniques that were used to create the splashView, building on the information from iPhone in Action.
There were two notable changes in this version of splashView.
The first thing I did was improve how the splashView got displayed. In the original version of the program, you had to add the splashView by hand as a subview of the main window. It restricted where you could run splashView, and it also required you to do the right thing or the class wouldn't work.
You'll notice that now you don't add the splashView as a subview at all(!). Somehow, the splashView is magically added to the main window.
It's actually down in the startSplash method, right at the start:
[[[[UIApplication sharedApplication] windows] objectAtIndex:0] addSubview:self];
This takes advantage of the fact that UIApplication has a listing of all the windows, and automatically places splashView atop the first one.
The second thing I did was add the protocol. This methodology is all covered in the creating delegate protocols article I already referenced. After setting up the protocol, I referenced it from dismissSplashFinish:
if (self.delegate != NULL
&& [self.delegate respondsToSelector:@selector(splashIsDone)]) {
[delegate splashIsDone];
}
As before, if you have questions, comments, or suggestions for improvements, please include them in the comments.
I can't at this time guarantee that the splashView works in iPhone OS 3.0, as I'm currently doing live development on 2.2.1.

The splash code works fine in iPhone 3.0 SDK, but does show a few warnings. My test app seems to work fine, although it's a bit off putting to see the warnings and highlights.
Have you had a look at the code in 3 yet, and will there be a revision to deal with this?
Posted by: Boyplunder | June 18, 2009 at 09:49 AM
Now that it's officially released, I'm going to try and get the 3.0 build over the weekend, and will look at the warnings next week.
Posted by: Shannon Appelcline | June 18, 2009 at 12:40 PM
Appreciate the response.
The warnings are all deprecated issues, which are a bit odd to me, as it would seem that if I change them to the new code way, the app becomes incompatible in earlier versions of the OS. At least I think it will. If you add a blog entry with your findings for the splashView, could you give your understanding of what deprecated code means in the wider sense?
Love the book, by the way. Never far from my desk.
Posted by: Boyplunder | June 19, 2009 at 02:06 AM
I'm now officially curious as to what you're seeing, because I just downloaded the final 3.0 build on Thursday, recompiled a program using the splash screen, and the splash screen compiled cleanly.
Posted by: iPhone in Action | June 23, 2009 at 03:56 PM
Shannon,
I get warnings that are all like the following:
[cell setTextColor:[UIColor whiteColor]];
"Warning: 'setTextColor:' is deprecated (decalred at /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UITableViewCell.h:199)
I get a couple of identical warnings with setText too. A slight syntax rewrite, as noted by Apple in the 3.0 notes makes them go away, but also then doesn't work in 2.2.1.
Having gone back to it since leaving the comment, I notice that cleaning targets means I don't get this the first build afterwards, then this each time after that. It always runs perfectly with no memory issues on Sim or Device. In the second build, I get a sixth warning that may be the crux of the matter. I get:
Warning: class 'AppNameAppDelegate' does not implement the 'SplashViewDelegate' protocol.
I get this with the line: mySplash.delegate = self;
I went back and checked the examples you supplied, but can't see what it thinks is the problem. It's starting to sound like something I've done. Darn!
Posted by: Boyplunder | June 26, 2009 at 02:42 AM
The first warning, about the table cells, doesn't come from the Splash Screen, but rather from something internal to your program (which uses cells). If you're writing a new program, it's probably worth using 3.0 standards from the start, as there's very good adoption rates.
See:
http://iphoneinaction.manning.com/iphone_in_action/2009/06/table-tricks-for-iphone-os-30.html
The second warning means that you didn't mark the SplashViewDelegate protocol in the header file of your app delegate class (where you're presumably using the protocol).
Here's an example from one of my programs:
@interface _E_XP_CalculatorAppDelegate : NSObject {
Posted by: Shannon Appelcline | June 26, 2009 at 03:52 PM
Let me try that again, as the delegation protocol link got eaten as HTML:
@interface _E_XP_CalculatorAppDelegate : NSObject UIApplicationDelegate,splashViewDelegate {
Posted by: Shannon Appelcline | June 26, 2009 at 03:53 PM
(There should be angle brackets around those delegate links, see p.179)
Posted by: Shannon Appelcline | June 26, 2009 at 03:54 PM
Shannon,
Not a warning or issue anywhere in the app. Your patience and help is much appreciated. I'll take a good look at the table tricks when I have a bit of time. Thanks.
Posted by: Boyplunder | June 27, 2009 at 08:53 AM
Thanks for the example code.
I'm getting a delay between the time I call startSplash and the time the image shows up on-screen.
The first thing I do in applicationDidFinishLaunching: is set up the window and run startSplash. I can see in my log that everything is executing ok in the SplashView instance.
Then I go on to set up my TabBarViewController and finish configuring the rest of my app.
Even though my logs indicate the SplashView should appear immediately, there's a long period of black before it actually appears on the screen - I think until the time applicationDidFinishLaunching: is complete.
After I run startSplash, I set up my individual view controllers and a disk cache. This can take a few seconds to complete, and is exactly what I'm trying to mask with SplashView.
I'm trying to figure out what is creating the delay, and how to minimize or eliminate it.
I added a [window setNeedsDisplay]; after the startSplash, but that didn't help.
All thoughts appreciated.
Posted by: Justin Kent | June 30, 2009 at 10:17 AM
PS - Is there a way to enable comment feeds on your blog, or am I missing the link somewhere? Would like to subscribe to this thread. Thanks -
Posted by: Justin Kent | June 30, 2009 at 10:22 AM
The black screen is a result of you having to wait for your app to get loaded. Make sure that your splash screen is called Default.png, as I suggest above, and you'll get it showing up as soon as it's possible (though you'll probably want to tune time your splashView timer at the backend).
Posted by: Shannon Appelcline | June 30, 2009 at 11:00 AM
(You should now see a comments feed if your browser supports auto-detection of them.)
Posted by: Shannon Appelcline | June 30, 2009 at 11:03 AM
Nice!!! That was it: at some point my Default.png got renamed to default.png, which prevented it from displaying on app load. Thanks a lot for the response.
I see the comment feed now.
Posted by: Justin Kent | June 30, 2009 at 04:57 PM
Any clue why this would be functioning fine in the simulator, but giving me a black screen on the device?
Posted by: Justin Kent | July 15, 2009 at 08:52 AM
That sounds like you didn't check the box that says to copy the file into the bundle when you added it to your program; thus, it exists on your local computer, but not on your iPhone.
Posted by: Shannon Appelcline | July 15, 2009 at 10:05 AM
Thanks so much for the tip - you put me on the right track.
The problem was related to the comment I posted a few comments back, where I was using default.png vs. Default.png.
The old file was still in my app bundle, and was not letting the new, correct file overwrite it.
I zapped the build directory and everything is working now!!!
Thanks again.
Posted by: Justin Kent | July 15, 2009 at 11:12 AM
I'm getting a warning:
Type id(UIApplicationDelegate) does not conform to SplashViewDelegate protocol
on this line:
NavAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.navigationController pushViewController:nextController animated:YES];
The first part of NavAppDelegate is:
@interface NavAppDelegate : NSObject UIApplicationDelegate,splashViewDelegate{
It's not letting me build for distribution while this warning exists.
Any ideas how to fix it?
edit: I found the answer: I had to cast it correctly
NavAppDelegate *delegate = (NavAppDelegate *)[[UIApplication sharedApplication] delegate];
Posted by: Andy D | August 24, 2009 at 11:14 AM
I'm almost there. Animation at the end works great but I have something strange at startup of app.
When the app starts you see the Default.png scaling as always. The for some reason it is lowerd approx 30 pixels and from that position on the animation kicks in.
I used your classes in my own project...
Posted by: Kemalski | September 23, 2009 at 05:18 PM
Great!
Thank you, great one.
I was thinking about making a splash screen, but a quick Google search landed me here.
I plugged your classes and it work in less than a minute. (iPhone SDK 3.1)
Thank you very much.
Note: i added SplashViewAnimationSlideDown to your code, liked it better scrolling down :)
Posted by: medopal | October 02, 2009 at 04:06 PM
Kemalski - You need to make your Default.png image with the size 320x460. I bet you have your image at 320x480, but you have to allow for the Carrier/Battery bar at the top of the screen.
Posted by: Stu Gisburne | October 15, 2009 at 10:51 AM
I use your classes in 3.0 and it works great in 3.0 simulator. When I download that into device testing, the image no longer show up, the delay is there before the next screen comes up.
Posted by: Cory | January 24, 2010 at 03:51 PM
Hi, let me ask you , I try to use this method in order to put splash screen in my project and i receive this error message :
"_kCAFillModeForwards", referenced from:
"_CATransform3DMakeAffineTransform", referenced from:
".objc_class_name_CABasicAnimation", referenced from:
let me know
tks
Posted by: Ricardo Mola | February 02, 2010 at 12:50 PM
Most likely, you didn't include the QuartzCore framework.
Posted by: Shannon Appelcline | February 03, 2010 at 01:43 PM
Hello, no matter what, only my Default.png shows no matter what image I initalize it with and also, no animation though it is calling the splashView code? Am I missing something obvious?
Posted by: jimijon | February 24, 2010 at 09:30 AM