iOS 5 Splash Page Transition - ios

My client wants his splash image to fade out and then show the UI. I am not sure how to do this. As of right now it just appears once it loads. Is there a simple way to do this ?

UIImageView *splash=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"splash"]];
[UIView animateWithDuration:1
animations:^{
splash.alpha = 0.0;
}
completion:^(BOOL finished)
{
[splash release];
}];

I was looking at this tutorial but decided not to implement it so I cant vouch as to whether it works or not but everything looks in check
http://www.dobervich.com/2010/10/22/fade-out-default-ipad-app-image-with-proper-orientation/
Beware though adding to much to your app startup is grounds for app rejection.
Avoid displaying an About window or a splash screen. In general, try
to avoid providing any type of startup experience that prevents people
from using your application immediately.
Source: Apple Developer Site

As I just explained on a closely related question, don't use splash screens! Please relate this to your client, who might not be familiar with the Human Interface Guidelines.
That said, if you can't convince you client otherwise, you can just fade out the UIImageView that I mentioned in my other response.

You can implement your own UIViewController as a splash screen:
#interface SplashScreenViewController : UIViewController {
UIImageView *splashView;
}
#end
//
#import "SplashScreenViewController.h"
#implementation SplashScreenViewController
#pragma mark - View lifecycle
- (void)loadView {
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
splashView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[splashView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
[self.view addSubview:splashView];
}
- (void)viewWillAppear:(BOOL)animated {
if (isIPad) {
if (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
splashView.image = [UIImage imageNamed:#"Default-Portrait~ipad.png"];
else
splashView.image = [UIImage imageNamed:#"Default-Landscape~ipad.png"];
}
else
splashView.image = [UIImage imageNamed:#"Default.png"];
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (isIPad) {
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation))
splashView.image = [UIImage imageNamed:#"Default-Portrait~ipad.png"];
else
splashView.image = [UIImage imageNamed:#"Default-Landscape~ipad.png"];
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (isIPad ? YES : UIInterfaceOrientationIsPortrait(interfaceOrientation));
}
#end
Then, after showing, you can hide this UIViewController with any transition you want.

Related

Show splash screen each time app becomes active

I want the splash screen to be displayed each time app becomes active. I have created a function showSplash which I call in applicationDidBecomeActive:
-(void)showSplash
{
UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"Default.png"]];
[self.window.rootViewController.view addSubview: splashScreen];
[self.window makeKeyAndVisible];
NSLog(#"begin splash");
[UIView animateWithDuration: 4.2
delay: 0.5
options: UIViewAnimationOptionCurveEaseOut
animations: ^{
splashScreen.alpha = 0.0;
}
completion: ^ (BOOL finished) {
[splashScreen removeFromSuperview];
NSLog(#"end splash");
}
];
}
This is how I call this function :
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self showSplash];
}
But no splash screen appears. Please correct me.
If you want the application to have a fresh start every time you get back to it, you could also disable background execution, as stated in the Apple Documentation (last section titled "Opting Out of Background Execution"):
If you do not want your app to run in the background at all, you can
explicitly opt out of background by adding the
UIApplicationExitsOnSuspend key (with the value YES) to your app’s
Info.plist file.
after adding the splash view - bring it to front
change
UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"Default.png"]];
[self.window.rootViewController.view addSubview: splashScreen];
[self.window makeKeyAndVisible];
to
UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"Default.png"]];
[self.window addSubview: splashScreen];
[self.window bringSubviewToFront: splashScreen]; //!
[self.window makeKeyAndVisible];
Please, ensure your window root view controller main view is the top most view in your App in the moment you want to show splash...
Check frame of splashScreen (UIImageView). Set its frame to bounds of your root view controller.
You can try to hunt the top view controller with a recursion like this:
- (UIViewController *)findTopViewController {
return [self topViewControllerFrom:self.window.rootViewController];
}
- (UIViewController *)topViewControllerFrom:(UIViewController *)vc {
if (vc.navigationController.visibleViewController != nil) {
return [self topViewControllerFrom:vc.navigationController.visibleViewController];
}
if (vc.tabBarController.selectedViewController != nil) {
return [self topViewControllerFrom:vc.tabBarController.selectedViewController];
}
return vc;
}
Now calling [self findTopViewController] should hopefully return the currently visible/top VC of your app, and you can do:
[[self findTopViewController].view addSubview:splashScreen];
...
you can do something like:
#import "AppDelegate.h"
#define kSplashScreen (UIScreen.mainScreen.bounds.size.height == 568) ? #"Default-568h" \
: (UIScreen.mainScreen.bounds.size.height == 667) ? #"Default-667" \
: (UIScreen.mainScreen.bounds.size.height == 736) ? #"Default-Portrait" \
: #"Default"
#interface AppDelegate ()
#property (nonatomic) UIWindow *splashWindow;
#property (nonatomic) UIWindow *keyWindow;
#property (nonatomic, getter=isSplashConfigured) BOOL splashConfigured;
#property (nonatomic, getter=isShowingSplash) BOOL showingSplash;
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self animateSplash];
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self showOrHideSplash];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self showOrHideSplash];
}
- (void)showOrHideSplash
{
[self.splashWindow setHidden:[self isShowingSplash]];
if ([self isShowingSplash])
{
[self.keyWindow makeKeyAndVisible];
}
else
{
[self.splashWindow makeKeyAndVisible];
[self animateSplash];
}
self.showingSplash = !self.showingSplash;
}
- (void)animateSplash
{
if ([self isSplashConfigured])
{
[self.window.rootViewController.view addSubview:self.splashWindow];
[self.window makeKeyAndVisible];
}
else
{
self.keyWindow = [[UIApplication sharedApplication] keyWindow];
self.splashWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.splashWindow.rootViewController = [[UIViewController alloc] init];
self.splashWindow.rootViewController.view.frame = self.splashWindow.bounds;
UIImageView *splashImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:kSplashScreen]];
splashImage.frame = self.splashWindow.bounds;
[self.splashWindow.rootViewController.view addSubview:splashImage];
[self.splashWindow makeKeyAndVisible];
[self.splashWindow setHidden:YES];
self.splashConfigured = YES;
}
NSLog(#"begin splash");
__weak AppDelegate* weakSelf = self;
[UIView animateWithDuration:4.2 delay:0.5 options:UIViewAnimationOptionCurveEaseOut animations: ^{
weakSelf.splashWindow.alpha = 1.0;
weakSelf.splashWindow.alpha = 0.0;
} completion: ^(BOOL finished) {
[weakSelf.splashWindow removeFromSuperview];
NSLog(#"end splash");
}];
}
#end
This is a bit cumbersome solution, but it works fine. The idea is add new UIWindow on top of all controllers
- (void)showSplash {
id <UIApplicationDelegate> appDelegate = [[UIApplication sharedApplication] delegate];
UIWindow *window = [[UIWindow alloc] initWithFrame:[appDelegate window].frame];
UIViewController *splashController = [UIViewController new];
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Default.png"]];
splashController.view = imgView;
window.rootViewController = splashController;
window.windowLevel = UIWindowLevelAlert;
window.hidden = NO;
[window makeKeyAndVisible];
[UIView animateWithDuration:4.2 delay:0.5 options:UIViewAnimationOptionCurveEaseOut animations:^{
window.alpha = 0.0;
} completion:^(BOOL finished) {
window.hidden = YES;
window.rootViewController = nil;
[[appDelegate window] makeKeyAndVisible];
[[appDelegate window] setNeedsDisplay];
}];
}
Please find below a solution for this problem.
Split the splash screen code into two methods; showSplash and hideSplash.
Call showSplash in the method applicationWillResignActive. In the method, create and add the imageView to rootViewController; set it's alpha to 0.0f and then animate it to alpha 1.0f. This is to make sure that the user doesn't see the imageView when the app is going to background.
Now call hideSplash in applicationDidBecomeActive. In hideSplash remove the imageView with animation. See the code below;
-(void)showSplash
{
_splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"Default"]];
[self.window.rootViewController.view addSubview:_splashScreen];
_splashScreen.alpha = 0.0f;
[UIView animateWithDuration:0.3f animations:^{
_splashScreen.alpha = 1.0f;
}];
}
- (void)hideSplash
{
[UIView animateWithDuration: 4.2
delay: 0.5
options: UIViewAnimationOptionCurveEaseOut
animations: ^{
_splashScreen.alpha = 0.0;
}
completion: ^ (BOOL finished) {
[_splashScreen removeFromSuperview];
NSLog(#"end splash");
}
];
}
- (void)applicationWillResignActive:(UIApplication *)application {
[self showSplash];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self hideSplash];
}
I hope this helps! :-)
Add
splashScreen.frame = self.window.rootViewController.view.frame;
below
UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"alertBg.png"]];
example
-(void)showSplash
{
UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"Default.png"]];
splashScreen.frame = self.window.rootViewController.view.frame;
[self.window.rootViewController.view addSubview: splashScreen];
[self.window makeKeyAndVisible];
NSLog(#"begin splash");
[UIView animateWithDuration: 4.2
delay: 0.5
options: UIViewAnimationOptionCurveEaseOut
animations: ^{
splashScreen.alpha = 0.0;
}
completion: ^ (BOOL finished) {
[splashScreen removeFromSuperview];
NSLog(#"end splash");
}
];
}
The best way to achieve this is to add the image in AppDelegate's window.
In the below code statusView is one of the view, which consist of some image. So add it to your AppDelegate's window as a subView
[[[[UIApplication sharedApplication] delegate] window] addSubview:statusView];
Now whenever you want it to appear for some amount of time, you show this view, but same time bring it to front.
-(void)showStatusView{
[UIView animateWithDuration:0.5 animations:^{
[[[[UIApplication sharedApplication] delegate] window] bringSubviewToFront:statusView];
statusView.alpha = 1;
}];
}
Better Call the above method on the AppDelegate's method didBecomeActive.
Also, show the splash screen as soon as application is going to resign active. This way, iOS will take the snapshot of the screen, which will be shown for fraction of seconds when the app is about to become active.
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self showStatusView];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self showStatusView];
}
Once the app is active, you can show the actual splash screen for some duration & then your usual app state.
First create your launch screen or image in didFinishLaunchingWithOptions function.
After this write your code like this-
Root view controller is not always the presented view controller. This can cause your splash screen to be hidden under bunch of other view controllers. Try using something like (swift syntex):
func getTopViewController() -> UIViewController?{
if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController{
while ((topController.presentedViewController) != nil) {
topController = topController.presentedViewController!
}
return topController
}
return nil
}
And add your splash view to the top view controller
launch your application normally every-time, call your method in applicationBecomeActive, and add you image view on Appdelegate.window and remove it after some time by timer.
[self.window addSubview: splashScreen];
You should use the following line:
[self.window addSubview: splashScreen];
instead of
[self.window.rootViewController.view addSubview: splashScreen];
You can reuse your launchScreen to show up instead of showing imageview. This comes handdy when you have complex launchscreen instead of single image as a splash screen.
func applicationWillResignActive(_ application: UIApplication) {
guard let window = UIApplication.shared.windows.last,
let launchScreen = UIStoryboard(name: "LaunchScreen", bundle: nil).instantiateInitialViewController(),
let launchView = launchScreen.view else {return}
launchView.tag = 8888
launchView.frame = window.bounds
launchView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
window.addSubview(launchView)
window.makeKeyAndVisible()
}
func applicationDidBecomeActive(_ application: UIApplication) {
guard let window = UIApplication.shared.windows.last,
let view = window.viewWithTag(8888) else {return}
view.removeFromSuperview()
}

iOS 8: Remove sensitive information from views before moving to the background

In iOS 7 my app presented an authentication screen when the app went into the background (by subscribing to UIApplicationDidEnterBackgroundNotification). The authentication controller removed sensitive information so the background screenshot did not show any user info. In iOS 8 this does not work anymore. The background screenshot now shows the view the user was last working in and not the authentication controller... even though when the app comes back into the foreground the authentication controller is active.
I found a work around for now. Instead of using UIApplicationDidEnterBackgroundNotification I can use name:UIApplicationWillResignActiveNotification however this causes a flash as the user leaves the app.
Is this a bug or did apple provide a new way to remove sensitive information from views before moving to the background.
Note: putting ignoreSnapshotOnNextApplicationLaunch in applicationWillResignActive:
and applicationDidEnterBackground: did not help.
Update: created a bug report
Similar approach to #Gurudev0777, but uses UIBlurEffect instead to obscure the content, and doesn't have the downside of worrying about different device screen metrics. Application delegate:
#define MY_BACKGROUND_SCREEN_TAG 1001//or any random but UNIQUE number.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Visual effect view for blur
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *blurView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[blurView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
[blurView setFrame:self.window.frame];
blurView.tag = MY_BACKGROUND_SCREEN_TAG;
[self.window addSubview:blurView];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// remove blur view if present
UIView *view = [self.window viewWithTag:MY_BACKGROUND_SCREEN_TAG];
if (view != nil)
{
[UIView animateWithDuration:0.2f animations:^{
[view setAlpha:0];
} completion:^(BOOL finished) {
[view removeFromSuperview];
}];
}
}
works like a charm...
Edited 5/18/2015: Thanks #Simeon Rice for observation about modal dialogs, revised to add blur view to self.window instead of rootViewController.view
Edited 8/23/2016: Thanks #tpankake for observation re: auto-resizing mask.
- (void)applicationWillResignActive:(UIApplication *)application
{
// show splash when app goto background
UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.window.bounds];
imageView.tag = 101; // assign image tag
// imageView.backgroundColor = [UIColor redColor];
[imageView setImage:[UIImage imageNamed:#"Default.png"]];
[UIApplication.sharedApplication.keyWindow.subviews.lastObject addSubview:imageView];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// remove splash when app goto foreground
UIImageView *imageView = (UIImageView *)[UIApplication.sharedApplication.keyWindow.subviews.lastObject viewWithTag:101]; // lookup image by image tag
[imageView removeFromSuperview];
}
here we are putting an imageview while the app animate to background -
-(void)applicationWillResignActive:(UIApplication *)application
{
imageView = [[UIImageView alloc]initWithFrame:[self.window frame]];
[imageView setImage:[UIImage imageNamed:#"Default#2x.png"]];
[self.window addSubview:imageView];
}
Here is the code to remove the imageview:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if(imageView != nil) {
[imageView removeFromSuperview];
imageView = nil;
}
}
It is working and tested many times.
*** Please test this scenario into the device not in simulator.

Disable camera rotation in iOS?

My code to add a UIImagePickerController:
picker = [[[UIImagePickerController alloc] init] autorelease];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.showsCameraControls = NO;
[self displayContentController:picker inView:cameraBoxView];
[self.view sendSubviewToBack:picker.view];
- (void)displayContentController:(UIViewController *)content inView:(UIView *)v {
//Delete the previous instance of the same view controller
for (UIViewController *vc in self.childViewControllers) {
if ([vc isKindOfClass:[content class]]) {
[vc removeFromParentViewController];
}
}
[self addChildViewController:content];
content.view.frame = v.frame;
[self.view addSubview:content.view];
[content didMoveToParentViewController:self];
if ([content isKindOfClass:[CCInnerNavigationController class]]) {
innerNavigationController = (CCInnerNavigationController *)content;
}
}
I have disabled all the device orientations except of portrait. But the image from camera is rotated. How to solve this issue in both iOS 6 and 7.
P.S. I understand that there are a lot of soludions but it seems they are too old because NOTHING of them works.
When you instatiate the UIImagePickerController you must also pass it a delegate. The delegate should be conform to 2 protocols UIImagePickerControllerDelegate and UINavigationControllerDelegate. The second makes possible to add some logic for rotation at runtime, implement this methods accordingly to what you want to achieve.
– navigationControllerPreferredInterfaceOrientationForPresentation:
– navigationControllerSupportedInterfaceOrientations:
I changed the following code:
imgView.image = img;
to:
imgView.image = [UIImage imageWithCGImage:img.CGImage scale:1 orientation:UIImageOrientationRight];
And now it works in both iOS 6 and 7. I don't know how it fixes this bug but it really works. Maybe image picker corrupts the image or image view and this code fixes it by creating a new image instance.

Imitating screenshot flash animation on iOS

Im looking for a way to copy the "blink" animation, that is played when pressing home+lock.
Does anyone know if this animation is available somehow?
On an iOS device you take a screenshot when you press home + lock and the screen flashes white. Do you mean this effect? If so, try this:
Add a UIView with a white background color to your view hierarchy such that it covers the whole screen. Then, start an animation that fades the opacity of this view to zero. On completion, remove the view from its superview:
[UIView animateWithDuration: 0.5
animations: ^{
whiteView.alpha = 0.0;
}
completion: ^(BOOL finished) {
[whiteView removeFromSuperview];
}
];
Try:
[UIView animateWithDuration:1 animations:^{
self.view.backgroundColor = [UIColor blackColor];
for (UIView *view2 in self.view.subviews) {
view2.backgroundColor = [UIColor blackColor];
}
}];
[UIView animateWithDuration:1 animations:^{
self.view.backgroundColor = [UIColor whiteColor];
for (UIView *view2 in self.view.subviews) {
view2.backgroundColor = [UIColor whiteColor];
}
}];
I have found very easy way to imitate exactly the Screenshot Flash Apple uses. I wish everyone try it at least once.
UIView * flashView = [[UIView alloc] initWithFrame:self.view.frame];
flashView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:flashView];
[UIView animateWithDuration:1 delay:0.3 options:0 animations:^{
flashView.alpha = 0;
} completion:^(BOOL finished)
{
[flashView removeFromSuperview];
}];
}
These examples gave me inspiration, but did not give me the desired effect. This is my attempt, looks pretty close to the real deal.
func mimicScreenShotFlash() {
let aView = UIView(frame: self.view.frame)
aView.backgroundColor = UIColor.whiteColor()
self.view.addSubview(aView)
UIView.animateWithDuration(1.3, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
aView.alpha = 0.0
}, completion: { (done) -> Void in
aView.removeFromSuperview()
})
}
Two problems with the current solutions:
putting views over other views can (in my experience with UICollectionView and other crap) trigger autolayout. Autolayout is bad. Autolayout makes the machine do a burst of work and can have side effects other than just calculating for no reason other than to burn CPU and battery. So, you don't want to give it reasons to autolayout, for instance, adding a subview to a view that really, really cares about keeping itself laid out nicely.
your view doesn't cover the whole screen necessarily, so if you want to flash the whole screen, you're better off using a UIWindow ... this should insulate from any view controllers that are touchy about having subviews added
This is my implementation, a category on UIView. I've included methods to take a screenshot before flashing the window, and saving it to the camera roll afterwards. Note that UIWindow seems to want to do its own animations when being added, it will normally fade in over maybe a third of a second. There may be a better way of telling it not to do this.
// stupid blocks
typedef void (^QCompletion)(BOOL complete);
#interface UIView (QViewAnimation)
+ (UIImage *)screenshot; // whole screen
+ (void)flashScreen:(QCompletion)complete;
- (UIImage *)snapshot; // this view only
- (void)takeScreenshotAndFlashScreen;
#end
#implementation UIView (QViewAnimation)
+ (UIImage *)screenshot;
{
NSArray *windows = [[UIApplication sharedApplication] windows];
UIWindow *window = nil;
if (windows.count) {
window = windows[0];
return [window snapshot];
} else {
NSLog(#"Screenshot failed.");
return nil;
}
}
- (UIImage *)snapshot;
{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0);
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
+ (void)flashScreen:(QCompletion)complete;
{
UIScreen *screen = [UIScreen mainScreen];
CGRect bounds = screen.bounds;
UIWindow * flash = [[UIWindow alloc] initWithFrame:bounds];
flash.alpha = 1;
flash.backgroundColor = [UIColor whiteColor];
[UIView setAnimationsEnabled:NO];
[flash makeKeyAndVisible];
[UIView setAnimationsEnabled:YES];
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationCurveEaseOut
animations:^{
flash.alpha = 0;
}
completion: ^(BOOL finished)
{
flash.hidden = YES;
[flash autorelease];
if (complete) {
complete(YES);
}
}];
}
- (void)takeScreenshotAndFlashScreen;
{
UIImage *image = [UIView screenshot];
[UIView flashScreen:^(BOOL complete){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0),
^{
UIImageWriteToSavedPhotosAlbum(image,self,#selector(imageDidFinishSaving:withError:context:),nil);
});
}];
}
- (void)imageDidFinishSaving:(UIImage *)image
withError:(NSError *)error
context:(void *)context;
{
dispatch_async(dispatch_get_main_queue(),^{
// send an alert that the image saved
});
}
#end

iOS: Animate splash screen out on top of status bar

OK, I get the concept of adding a UIImageView as soon as the app launches, and animating it out to fake the splash animation. However, the status bar interferes.
I need a UIImageView on top of everything, including the status bar, and while it fades away, the app is shown with the status bar. Hence, settings the Status bar initially hidden, then animating it in is not a viable option.
What you require is a second UIWindow with a windowLevel of UIWindowLevelStatusBar or higher. You would create two UIWindow objects in your application delegate, one with your regular view hierarchy, the other with the image, and animate the second to fade out (or however else you need to animate). Both windows should be visible, with the splash window being on top.
This approach is complicated, as you might have problems with rotation, depending on your regular view hierarchy. We've done this in our software, and it works well.
EDIT:
Adapted Solution (window approach, very simple):
UIImageView* splashView = [[UIImageView alloc] initWithImage:[UIImage imageWithBaseName:#"Default"]];
[splashView sizeToFit];
UIViewController* tmpVC = [UIViewController new];
[tmpVC.view setFrame:splashView.bounds];
[tmpVC.view addSubview:splashView];
// just by instantiating a UIWindow, it is automatically added to the app.
UIWindow *keyWin = [UIApplication sharedApplication].keyWindow;
UIWindow *hudWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0.0f, -20.0f, keyWin.frame.size.width, keyWin.frame.size.height)];
[hudWindow setBackgroundColor:[UIColor clearColor]];
[hudWindow setRootViewController:tmpVC];
[hudWindow setAlpha: 1.0];
[hudWindow setWindowLevel:UIWindowLevelStatusBar+1];
[hudWindow setHidden:NO];
_hudWin = hudWindow;
[UIView animateWithDuration:2.3f animations:^{
[_hudWin setAlpha:0.f];
} completion:^(BOOL finished) {
[_hudWin removeFromSuperview];
_hudWin = nil;
}];
Finally, credit goes to this guy.
A more simple approach would be to launch your application with the status bar hidden, have the view you would like to animate on the top of the view hierarchy, and after the animation is finished, display the status bar using [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide]
You can add a subview to the App's UIWindow. Set the Y coordinate of the UIImageView's frame to -20 pixels in order to handle the status bar.
Add the Default PNG image to your window and tag it:
static const NSInteger kCSSplashScreenTag = 420; // pick any number!
UIImageView *splashImageView;
// Careful, this wont work for iPad!
if ( [[UIScreen mainScreen] bounds].size.height > 480.0f ) // not best practice, but works for detecting iPhone5.
{
splashImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Default-568h"]];
}
else
{
splashImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Default"]];
}
splashImageView.frame = CGRectMake(0.0f, -20.0f, splashImageView.image.size.width, splashImageView.image.size.height);
splashImageView.tag = kCSSplashScreenTag;
[self.window addSubview:splashImageView];
[splashImageView release];
[self _fadeOutSplaceImageView];
Then fade it out
- (void)_fadeOutSplashImageView
{
UIView *splashview = [self.window viewWithTag:kCSSplashScreenTag];
if ( splashview != nil )
{
[UIView animateWithDuration:0.5
delay:0.0
options:0
animations:^{
splashview.alpha = 0.0f;
}
completion:^(BOOL finished) {
[splashview removeFromSuperview];
}];
}
}

Resources