I have a simple iPhone application that loads very quickly, so the splash screen only displays for a fraction of a second. Is there any way to control how long the splash screen displays? I have searched around, and have not found anything that seems like it would work. Do I have to create a subview with my splash image? How would I control its display time and switch between the subview and the mainview?
While I agree with the views expressed here and in the other question about why you should not "abuse" the default screen, it seems to me quite trivial to achieve this effect:
When starting up, simply put up a view that looks exactly like the splash screen and use an NSTimer to dismiss it. Really quite easy.
// viewDidLoad
[self performSelector:#selector(dismiss)
withObject:nil
afterDelay:yourTimeIntervalInSectons];
// dismiss
[self performSegueWithIdentifier:#"ID" sender:nil];
However, don't have the splash screen come on each time the application becomes active. I once did this for a very specific and useful purpose in the context of my app - but Apple rejected it. Hey, they even called me on Saturday evening to explain it to me.
While I agree with all that's been told here, I had to implement a splash screen with a timer once as well, so here's the code:
- (void)showSplashWithDuration:(CGFloat)duration
{
// add splash screen subview ...
UIImage *image = [UIImage imageNamed:#"Default.png"];
UIImageView *splash = [[UIImageView alloc] initWithImage:image];
splash.frame = self.window.bounds;
splash.autoresizingMask = UIViewAutoresizingNone;
[self.window addSubview:splash];
// block thread, so splash will be displayed for duration ...
CGFloat fade_duration = (duration >= 0.5f) ? 0.5f : 0.0f;
[NSThread sleepForTimeInterval:duration - fade_duration];
// animate fade out and remove splash from superview ...
[UIView animateWithDuration:fade_duration animations:^ {
splash.alpha = 0.0f;
} completion:^ (BOOL finished) {
[splash removeFromSuperview];
}];
}
Just call the function somewhere in your AppDelegate's -applicationDidFinishLaunching:withOptions: method
#asgeo1: code works just fine for me (I've used similar code in several projects). I've added an example project on my Dropbox for your convenience.
Don't do this and/or read why here
iOS Duration of Splash Screen (Default.png)
It does really make no sense to extend the duration of the Default.png.
Now, I completely agree with the above posts that you shouldn't do this, but if you still wish to it can be achieved very easily by adding the following to your AppDelegate.m.
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
sleep(2);
}
The "2" represents how many seconds to sleep for. It will accept values like ".5"
Related
Is it possible to implement a smooth transition when the app loads, from the launch image to the first view?
The default behavior is on/off, with an immediate change: the launch image appears, then it instantaneously disappears to let the main view controller take place. I'd like to implement some fading or zooming in or out.
Is this possible?
Thank you!
There's no framework support, but you can get that result if you do it yourself, manually. Depending on what your launch image is, and what your UI looks like, you can do it in different ways, but basically: make your first view controller load and display your default.png image in an image view when it loads up. Then animate a fade out of that image to reveal your actual UI.
Modified Dancreek's answer to do it all in AppDelegate application:didFinishLaunchingWithOptions. I like this because the code is guaranteed to only run at app start, and it's not polluting any of the view controllers.
It's very simple:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// set up your root view and stuff....
//.....(do whatever else you need to do)...
// show the main window, overlay with splash screen + alpha dissolve...
UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Default.png"]];
[self.window addSubview:splashScreen];
[self.window makeKeyAndVisible];
[UIView animateWithDuration:0.3 animations:^{splashScreen.alpha = 0.0;}
completion:(void (^)(BOOL)) ^{
[splashScreen removeFromSuperview];
}
];
}
You are in luck. I just did this a few min ago. You need a splash screen. An image on your view that is exactly the same as your default image that the device loads. Then in your app have it dismiss with a fade animation called from the viewDidAppear function
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self performSelector:#selector(killSplashScreen) withObject:nil afterDelay:1.0];
}
- (void)killSplashScreen {
[UIView animateWithDuration:0.5 animations:^{splashScreen.alpha = 0.0;} completion:NULL];
}
We often use something called "splashView" to do this. It was written by Shannon Applecline and available under the CC license. You will have to do some Googling to find it.
//
// splashView.h
// version 1.1
//
// Created by Shannon Appelcline on 5/22/09.
// Copyright 2009 Skotos Tech Inc.
//
// Licensed Under Creative Commons Attribution 3.0:
// http://creativecommons.org/licenses/by/3.0/
// You may freely use this class, provided that you maintain these attribute comments
//
// Visit our iPhone blog: http://iphoneinaction.manning.com
//
How do I make a top to down or down to top animation when I click the add (plus) button on the iPhone?
If you are looking for the "Built In" API, Alex is correct. And that works perfectly well.
If you are looking to understand how do make your own animations, you have several options in Core Animation
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreAnimation_guide/Introduction/Introduction.html
but a great starting point is simply the UIView animateWithDuration
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIView_Class/UIView/UIView.html
you should also get to know the CGAffineTransform
putting this all together, here is an example of sliding a view onto screen from the bottom right, having it fade in at the same time. (I dont really know a situation where I would want to do that, but its an example).
I put this in the app delegate so its easy to simply "paste" into a new project. Normally you would not put any views of this nature directly into the window.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UIWindow *w = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]];;
self.window = w; //property defined in the .h file
[w release];
UIView *v = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
v.backgroundColor = [UIColor redColor];
v.center=self.window.center;
v.alpha=0;
[self.window addSubview:v];
//if you ran the code to here, you would see a square in the center of the window.
//now lets move the square off (off screen) with a transform and then animate it back (on screen)
CGAffineTransform t = CGAffineTransformMakeTranslation(160+50, 240+50); //place the view just off screen, bottom right
v.transform=t;
//if you ran the code to here, you wouldnt see anything as the squre is placed just off screen, bottomr right
[UIView animateWithDuration:.5 //make the animation last .5 seconds
delay:.3 //wait .3 seconds before performing the animation
options:UIViewAnimationOptionCurveEaseOut //slow down as it reaches its destination
animations:^
{
v.transform=CGAffineTransformIdentity; //reset any transformation
v.alpha=1.0; //fade it in
}
completion:^(BOOL finished){} //nothing to do when it completes
];
[self.window makeKeyAndVisible];
return YES;
}
I think you're thinking of presentModalViewController; you can use it to present a new screen that slides up from the bottom of the screen.
So I have an iPhone app that needs to have 2 splash screens.
During the first one I need to check if my sqlite database is there and has all the correct values for a specific table. After 3 seconds, the second splash screen should fire, after another 3 seconds, my first view comes up.
I already have a rootcontroller, its of type UITabBarController. So I just need to make sure that loads after the second splash screen completes. I already know I need a UIImageView but I dont know where I should put it or how I'm supposed to go about it. The two images I have are named
splash1_placeholder.png and splash2_placeholder.png they are both 480x320px
Why 3 seconds? Why not "until my methods complete?" People hate splash screens. That's why apple (and everybody else) discourages from using them.
Maybe you should speed up your configuration logic.
Nobody wants to read your company name for 6 seconds (plus the time the real default splash image will be displayed) when they sit in the bus and want to use your app for the next 30 seconds.
Anyway, here is how you would implement it:
Find the code where you add the tabbarcontroller to the window, replace it with the first splashscreen image.
Set up a method that fires after 3 seconds that removes the first splash from the window and adds the second one.
After another 3 seconds you remove the second splash screen from the window and finally add your tabbarcontroller.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIImageView *imageView = [[[UIImageView alloc] initWithFrame:self.window.bounds] autorelease];
UIImage *image = [UIImage imageNamed:#"splash1_placeholder.png"];
if (!image) {
NSLog(#"Something went wrong trying to get the UIImage. Check filenames");
}
imageView.image = image;
[self.window addSubview:imageView];
[self.window makeKeyAndVisible];
[self performSelector:#selector(removeFirstSplash:) withObject:imageView afterDelay:3];
return YES;
}
- (void)removeFirstSplash:(UIImageView *)oldImageView {
UIImageView *imageView = ...
[self.window addSubview:imageView];
[self performSelector:#selector(removeSecondSplash:) withObject:imageView afterDelay:3];
[oldImageView removeFromSuperView];
}
- (void)removeSecondSplash:(UIImageView *)oldImageView {
[self.window addSubview:self.tabController.view];
[oldImageView removeFromSuperView];
}
not entirely perfect, but you could use it as a starting point.
For example there is no need to remove the first UIImageView, you could just replace the image. Don't know why I thought I should remove it.
I am building an app that has picture viewing capabilities. I have wrestled the UIScrollView beast to the ground (hope to post my scrollview knowledge RSN) and am now trying to duplicate some of the other visual effects of the iPhone photos app. specifically, when viewing an image, I would like to dissolve the controls and bars away.
I have a method that toggles visibility of the status bar, navigation bar, and tab bar, leaving just the scrollview with an image. The scrollview is full screen. I have a timer that fires 3 seconds after the user does something (single taps the screen, views the next image, etc.) and in the timerFired method, I call my method to turn off the bars. a single tap of the screen turns on the bars. here's the method to toggle the full screen state.
- (void)setFullScreen:(BOOL)fullScreen {
// reset the timer
[myTimer invalidate];
[myTimer release];
myTimer = nil;
// start animation section
[UIView beginAnimations:nil context:nil];
// toggle the status bar
[[UIApplication sharedApplication] setStatusBarHidden:fullScreen animated:YES];
[UIView setAnimationDuration:UINavigationControllerHideShowBarDuration];
CGFloat alpha = fullScreen ? 0.0 : 1.0;
// change the alpha to either 0 or 1 based on hiding or showing the bars
self.navigationController.navigationBar.alpha = alpha;
self.tabBarController.tabBar.alpha = alpha;
// do the animations!
[UIView commitAnimations];
// restart the timer after we show the bars
if (!fullScreen) {
myTimer = [[NSTimer timerWithTimeInterval:3.0 target:self selector:#selector(timerFired:) userInfo:nil repeats:NO] retain];
[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSDefaultRunLoopMode];
}
}
This basically works, BUT, it doesn't look as good as the photos app. I am animating the alpha values as I believe that this looks more like the photos app instead of the using the hidden with Animation methods available. My problem is doing the same for the status bar.
my questions:
(1) is there a UIView for the the status bar?
(2) is there a way to change the alpha property of the status bar?
(3) is the statusbar in another UIWindow?
(4) is there another way to achieve this using "legal" methods (I need to put this app in the app store)?
I've dumped the windows property of the UIApplication and there was only 1 window and I've crawled the view hierarchy and there was not an obvious view for the status bar.
any ideas?
The status bar is created by SpringBoard itself, it is of class SBStatusBar (which IIRC inherits from UIWindow). It is not accessible to app store applications.
I'm using a UIWebView with text in it. When the iPhone is rotated to landscape, text doesn't fill the now wider UIWebView width. I'm using P (paragraph) tags, which should not affect content filling landscape's width. The line breaks that are visible in portrait remain the same in landscape. In Interface Builder, I haven't changed anything. In the IB Inspector, Web View Size has all solid bars under AutoSizing, which means it should fill to the landscape width right?
Here is a tweak though not a good thing to do, and something should be handled by apple itself
As you've noticed that things workfine when WebView is initialized in portrait and then you turn it to landscape. So.. what you can do is always initialize your webview with portrait bounds, add a selector which calls back after 2~3 seconds and sets the frame of webView according to your requirement.
Now as the contents started loading when the frame size of your webview were according to portrait (say 320,460) so converting your webview to landscape will automatically adjust your web view if you have this line in your code
[webViewObjet_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
Below is the snippet of code
- (id) initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
webViewObjet_ = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
.....
}
}
- (void) webViewDidStartLoad:(UIWebView *)webView
{
.....
[self performSelector:#selector(chuss) withObject:nil afterDelay:3];
// call the function chuss after 3 second
}
- (void) chuss
{
webViewObjet_.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
[webViewObjet setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
}
Now tried around with the same problem, finally did it after looking detailed at "WhichWayIsUp"-Sample from Apple.
To keep it short:
1) Disable in the View Inspector the |--| and <-->
2) `switch the View Mode from the Webview to "Aspect Fill"
Et voila ;)
Keep the vibes,
Maniac
I have the same problem. Reloading does not work, the only thing that seems to help a bit is to add the following line to the code:
self.view.autoresizingMask =
UIViewAutoresizingFlexibleWidth;
(I place it in the willAnimateFirstHalfOfRotationToInterfaceOrientation function)
It still keeps a small white margin at the right, but its far better than the default. Note: you should apply this on the self.view and not on the UIWebView instance, that won't work.
Waiting for a solution from Apple..
Pieter
This will sound strange, but it works:
If the UIWebView is inside a UINavigationController, it will all work just fine. I had the same problem, so I just wrapped it up in a UINavigationController and the problem was gone.
For some reason, UINavigationController makes rotations work like a charm.