Skip to content

Instantly share code, notes, and snippets.

@tqc
Created April 19, 2012 14:36
Show Gist options
  • Save tqc/2421350 to your computer and use it in GitHub Desktop.
Save tqc/2421350 to your computer and use it in GitHub Desktop.
PhoneGap / Cordova Splash Screen Fix
- (void) hideSplashScreen
{
[UIView beginAnimations:@"fade out" context:nil];
[UIView setAnimationDelay: 0.2];
[UIView setAnimationDuration:0.3];
self.splashView.alpha = 0.0;
[UIView commitAnimations];
}
#ifdef CORDOVA_FRAMEWORK
#import <Cordova/CDVViewController.h>
#else
#import "CDVViewController.h"
#endif
@interface MainViewController : CDVViewController
@property (nonatomic, readwrite, retain) UIImageView *splashView;
- (void) showSplashScreen;
- (void) hideSplashScreen;
@end
#import "MainViewController.h"
#define degreesToRadian(x) (M_PI * (x) / 180.0)
@implementation MainViewController
@synthesize splashView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void) hideSplashScreen
{
[UIView beginAnimations:@"fade out" context:nil];
[UIView setAnimationDelay: 0.2];
[UIView setAnimationDuration:0.3];
self.splashView.alpha = 0.0;
[UIView commitAnimations];
}
+ (BOOL) isIPad
{
#ifdef UI_USER_INTERFACE_IDIOM
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#else
return NO;
#endif
}
+ (NSString*) resolveImageResource:(NSString*)resource
{
NSString* systemVersion = [[UIDevice currentDevice] systemVersion];
BOOL isLessThaniOS4 = ([systemVersion compare:@"4.0" options:NSNumericSearch] == NSOrderedAscending);
// the iPad image (nor retina) differentiation code was not in 3.x, and we have to explicitly set the path
if (isLessThaniOS4)
{
if ([[self class] isIPad]) {
return [NSString stringWithFormat:@"%@~ipad.png", resource];
} else {
return [NSString stringWithFormat:@"%@.png", resource];
}
}
return resource;
}
- (void) showSplashScreen
{
if (self.splashView != nil) return;
NSString* launchImageFile = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UILaunchImageFile"];
if (launchImageFile == nil) { // fallback if no launch image was specified
launchImageFile = @"Default";
}
NSString* orientedLaunchImageFile = nil;
CGAffineTransform startupImageTransform = CGAffineTransformIdentity;
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
UIInterfaceOrientation statusBarOrientation = [UIApplication sharedApplication].statusBarOrientation;
BOOL isIPad = [[self class] isIPad];
UIImage* launchImage = nil;
// default to center of screen as in the stndard implementation. This will produce the 20px jump
CGPoint center = CGPointMake((screenBounds.size.width / 2), (screenBounds.size.height / 2));
if (isIPad)
{
if (!UIDeviceOrientationIsValidInterfaceOrientation(deviceOrientation)) {
deviceOrientation = (UIDeviceOrientation)statusBarOrientation;
}
switch (deviceOrientation)
{
case UIDeviceOrientationLandscapeLeft: // this is where the home button is on the right (yeah, I know, confusing)
{
orientedLaunchImageFile = [NSString stringWithFormat:@"%@-Landscape", launchImageFile];
startupImageTransform = CGAffineTransformMakeRotation(degreesToRadian(90));
center.x -= MIN(statusBarFrame.size.width, statusBarFrame.size.height)/2;
}
break;
case UIDeviceOrientationLandscapeRight: // this is where the home button is on the left (yeah, I know, confusing)
{
orientedLaunchImageFile = [NSString stringWithFormat:@"%@-Landscape", launchImageFile];
startupImageTransform = CGAffineTransformMakeRotation(degreesToRadian(-90));
center.x += MIN(statusBarFrame.size.width, statusBarFrame.size.height)/2;
}
break;
case UIDeviceOrientationPortraitUpsideDown:
{
orientedLaunchImageFile = [NSString stringWithFormat:@"%@-Portrait", launchImageFile];
startupImageTransform = CGAffineTransformMakeRotation(degreesToRadian(180));
center.y -= MIN(statusBarFrame.size.width, statusBarFrame.size.height)/2;
}
break;
case UIDeviceOrientationPortrait:
default:
{
orientedLaunchImageFile = [NSString stringWithFormat:@"%@-Portrait", launchImageFile];
startupImageTransform = CGAffineTransformIdentity;
center.y += MIN(statusBarFrame.size.width, statusBarFrame.size.height)/2;
}
break;
}
launchImage = [UIImage imageNamed:[[self class] resolveImageResource:orientedLaunchImageFile]];
}
else // not iPad
{
orientedLaunchImageFile = @"Default";
launchImage = [UIImage imageNamed:[[self class] resolveImageResource:orientedLaunchImageFile]];
}
if (launchImage == nil) {
NSLog(@"WARNING: Splash-screen image '%@' was not found. Orientation: %d, iPad: %d", orientedLaunchImageFile, deviceOrientation, isIPad);
}
self.splashView = [[[UIImageView alloc] initWithImage:launchImage] autorelease];
self.splashView.tag = 1;
self.splashView.center = center;
self.splashView.autoresizingMask = (UIViewAutoresizingFlexibleWidth & UIViewAutoresizingFlexibleHeight & UIViewAutoresizingFlexibleLeftMargin & UIViewAutoresizingFlexibleRightMargin);
[self.splashView setTransform:startupImageTransform];
[self.view.superview addSubview:self.splashView];
/*
* The Activity View is the top spinning throbber in the status/battery bar. We init it with the default Grey Style.
*
* whiteLarge = UIActivityIndicatorViewStyleWhiteLarge
* white = UIActivityIndicatorViewStyleWhite
* gray = UIActivityIndicatorViewStyleGray
*
*/
/*
NSString* topActivityIndicator = [self.settings objectForKey:@"TopActivityIndicator"];
UIActivityIndicatorViewStyle topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray;
if ([topActivityIndicator isEqualToString:@"whiteLarge"]) {
topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhiteLarge;
} else if ([topActivityIndicator isEqualToString:@"white"]) {
topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhite;
} else if ([topActivityIndicator isEqualToString:@"gray"]) {
topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray;
}
self.activityView = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:topActivityIndicatorStyle] autorelease];
self.activityView.tag = 2;
id showSplashScreenSpinnerValue = [self.settings objectForKey:@"ShowSplashScreenSpinner"];
// backwards compatibility - if key is missing, default to true
if (showSplashScreenSpinnerValue == nil || [showSplashScreenSpinnerValue boolValue]) {
[self.view.superview addSubview:self.activityView];
}
self.activityView.center = self.view.center;
[self.activityView startAnimating];
*/
[self.view.superview layoutSubviews];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return [super shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
@end
- (void) showSplashScreen
{
if (self.splashView != nil) return;
NSString* launchImageFile = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UILaunchImageFile"];
if (launchImageFile == nil) { // fallback if no launch image was specified
launchImageFile = @"Default";
}
NSString* orientedLaunchImageFile = nil;
CGAffineTransform startupImageTransform = CGAffineTransformIdentity;
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
UIInterfaceOrientation statusBarOrientation = [UIApplication sharedApplication].statusBarOrientation;
BOOL isIPad = [[self class] isIPad];
UIImage* launchImage = nil;
// default to center of screen as in the stndard implementation. This will produce the 20px jump
CGPoint center = CGPointMake((screenBounds.size.width / 2), (screenBounds.size.height / 2));
if (isIPad)
{
if (!UIDeviceOrientationIsValidInterfaceOrientation(deviceOrientation)) {
deviceOrientation = (UIDeviceOrientation)statusBarOrientation;
}
switch (deviceOrientation)
{
case UIDeviceOrientationLandscapeLeft: // this is where the home button is on the right (yeah, I know, confusing)
{
orientedLaunchImageFile = [NSString stringWithFormat:@"%@-Landscape", launchImageFile];
startupImageTransform = CGAffineTransformMakeRotation(degreesToRadian(90));
center.x -= MIN(statusBarFrame.size.width, statusBarFrame.size.height)/2;
}
break;
case UIDeviceOrientationLandscapeRight: // this is where the home button is on the left (yeah, I know, confusing)
{
orientedLaunchImageFile = [NSString stringWithFormat:@"%@-Landscape", launchImageFile];
startupImageTransform = CGAffineTransformMakeRotation(degreesToRadian(-90));
center.x += MIN(statusBarFrame.size.width, statusBarFrame.size.height)/2;
}
break;
case UIDeviceOrientationPortraitUpsideDown:
{
orientedLaunchImageFile = [NSString stringWithFormat:@"%@-Portrait", launchImageFile];
startupImageTransform = CGAffineTransformMakeRotation(degreesToRadian(180));
center.y -= MIN(statusBarFrame.size.width, statusBarFrame.size.height)/2;
}
break;
case UIDeviceOrientationPortrait:
default:
{
orientedLaunchImageFile = [NSString stringWithFormat:@"%@-Portrait", launchImageFile];
startupImageTransform = CGAffineTransformIdentity;
center.y += MIN(statusBarFrame.size.width, statusBarFrame.size.height)/2;
}
break;
}
launchImage = [UIImage imageNamed:[[self class] resolveImageResource:orientedLaunchImageFile]];
}
else // not iPad
{
orientedLaunchImageFile = @"Default";
launchImage = [UIImage imageNamed:[[self class] resolveImageResource:orientedLaunchImageFile]];
}
if (launchImage == nil) {
NSLog(@"WARNING: Splash-screen image '%@' was not found. Orientation: %d, iPad: %d", orientedLaunchImageFile, deviceOrientation, isIPad);
}
self.splashView = [[[UIImageView alloc] initWithImage:launchImage] autorelease];
self.splashView.tag = 1;
self.splashView.center = center;
self.splashView.autoresizingMask = (UIViewAutoresizingFlexibleWidth & UIViewAutoresizingFlexibleHeight & UIViewAutoresizingFlexibleLeftMargin & UIViewAutoresizingFlexibleRightMargin);
[self.splashView setTransform:startupImageTransform];
[self.view.superview addSubview:self.splashView];
[self.view.superview layoutSubviews];
}
- (void) webViewDidFinishLoad:(UIWebView*) theWebView
{
// only valid if FooBar.plist specifies a protocol to handle
if (self.invokeString)
{
// this is passed before the deviceready event is fired, so you can access it in js when you receive deviceready
NSString* jsString = [NSString stringWithFormat:@"var invokeString = \"%@\";", self.invokeString];
[theWebView stringByEvaluatingJavaScriptFromString:jsString];
}
// Black base color for background matches the native apps
theWebView.backgroundColor = [UIColor blackColor];
[((MainViewController*)self.viewController) hideSplashScreen];
return [self.viewController webViewDidFinishLoad:theWebView];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment