56

Is it possible to display the Default.png for a specified number of seconds? I have a client that wants the splash screen displayed for longer than its current time.

They would like it displayed for 2 - 3 seconds.

EDIT: Told the client it would be against HIG and we moved forward without implementing anything.

gotnull
  • 26,454
  • 22
  • 137
  • 203

22 Answers22

67

No, the default.png is shown while your app starts up.

You can add a new viewcontroller which will display the default.png in the application didFinishLoading.

This way you display the default.png a bit longer.

You should only show the default.png if you are loading data, which could take some time. As the appstore guidelines state, you should not delay starting of you are any longer than necessary.

gotnull
  • 26,454
  • 22
  • 137
  • 203
rckoenes
  • 69,092
  • 8
  • 134
  • 166
  • 9
    do it this way and do NOT put your app to sleep as suggested in the other answers. +1 for correct answer. – Till Apr 11 '11 at 07:44
  • if i put my app to sleep..then apple will reject my app? – Hari1251 Mar 20 '13 at 06:49
  • 3
    Or better yet don't do it at all. It goes against the HIG and is just plain stupid as far as UX goes. – powerj1984 Apr 09 '13 at 01:13
  • I know it is one more workaround but how about putting a large sized image/resource in the app and not using it. iOS will try to load it and it will take more time to load app. Hence, more time for splash screen. – Farhan Hafeez Apr 15 '13 at 07:07
  • Delay the startup of your app may result in your app being killed by the watchdog for taking to long to load. So never ever delay startup. – rckoenes Sep 19 '13 at 10:21
  • How can I programmatically add a view controller in the application didFinishLoading? I just want to experiment with this. Im against going against Apple guidelines in general. – cheznead Sep 04 '17 at 09:48
36

You can also use NSThread:

[NSThread sleepForTimeInterval:(NSTimeInterval)];

You can put this code in to first line of applicationDidFinishLaunching method.

For example, display default.png for 5 seconds.

- (void) applicationDidFinishLaunching:(UIApplication*)application
{
   [NSThread sleepForTimeInterval:5.0];
}
Aron Rotteveel
  • 81,193
  • 17
  • 104
  • 128
Chetan Bhalara
  • 10,326
  • 6
  • 32
  • 51
  • 1
    Its simply perfect. Thanx Man. :) – Pratik Somaiya May 28 '13 at 04:28
  • 4
    Delay the startup of your app may result in your app being killed by the watchdog for taking to long to load. So never ever delay startup. – rckoenes Sep 19 '13 at 10:23
  • 27
    OMG! please don't use this approach, is simply TERRIBLE, you are blocking the app main thread freezing the application, as explained by @rckoenes the app can be killed, is against ANY apple guidelines and is absolutely ugly. instead implement your VC and display it – Kappe Jan 22 '16 at 15:17
  • OMG! This is so terrible. Do not ever do this. Please. It will possibly just get your app killed before it even launches. Don't do this. – Fogmeister May 14 '18 at 08:42
24

This is super hacky. Don’t do this in production.


Add this to your application:didFinishLaunchingWithOptions::

Swift:

// Delay 1 second
RunLoop.current.run(until: Date(timeIntervalSinceNow: 1.0))

Objective C:

// Delay 1 second
[[NSRunLoop currentRunLoop]runUntilDate:[NSDate dateWithTimeIntervalSinceNow: 1.0]];
Daniel Storm
  • 18,301
  • 9
  • 84
  • 152
  • Nice one. I would have used this solution, but it requires me to move a bunch of initialisation stuff from the default thread (main) to another thread and it might create new unexpected behaviours to resolve. – Arik Segal Jan 09 '18 at 16:43
  • @Daniel Storm. Can this be a cause of app rejection by Apple? – zulkarnain shah Feb 28 '18 at 17:36
  • 1
    @zulkarnainshah Yes, because it can cause the watchdog, which monitors app, to kill your app. Which apple will se a crash and reject your app. You should never delay the start up of your app,**never**!!! – rckoenes Mar 15 '18 at 13:35
  • Delay is not a good idea, you ll freeze your app for one sec. There should be a better way. – Yucel Bayram Sep 11 '19 at 13:12
  • 1
    @YucelBayram completely agree. Should mirror the launch screen on root and push/replace to initial screen when ready. – Daniel Storm Sep 11 '19 at 14:00
14

If you are using the LaunchScreen.storyboard you can obtain the same view controller and present it: (remember to set the storyboard id, for example "LaunchScreen")

func applicationDidBecomeActive(application: UIApplication) {

        let storyboard = UIStoryboard(name: "LaunchScreen", bundle: nil)
        let vc = storyboard.instantiateViewControllerWithIdentifier("LaunchScreen")
self.window!.rootViewController!.presentViewController(vc, animated: false, completion: nil)
        }

SWIFT 4

let storyboard = UIStoryboard(name: "LaunchScreen", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "LaunchScreen")
 self.window!.rootViewController!.present(vc, animated: false, completion: nil)
mohsen
  • 4,698
  • 1
  • 33
  • 54
Kappe
  • 9,217
  • 2
  • 29
  • 41
8

In Xcode 6.1, Swift 1.0 to delay the launch screen:

Add the below statement in e didFinishLaunchingWithOptions meth in AppDelegateod

NSThread.sleepForTimeInterval(3)

Here, time can be passed based on your requirement.

SWIFT 5

Thread.sleep(forTimeInterval: 3)
Teja Kumar Bethina
  • 3,486
  • 26
  • 34
Mr. Roddy
  • 147
  • 1
  • 5
  • 1
    Same as I said before: Delaying the startup of your app may result in your app being killed by the watchdog for taking to long to load. So never ever delay startup. – rckoenes Oct 04 '16 at 07:30
8

Swift 3

This is doable in a safe way by presenting the splash controller for what ever time you specify then remove it and display your normal rootViewController.

  1. First in LaunchingScreen.storyboard give your controller a StoryBoard identifier let's say "splashController"
  2. In Main.storyboard give your initial viewController a StoryBoard identifier let's say "initController". -This could be nav or tab bar etc...-

In AppDelegate you can create these 2 methods:

  1. private func extendSplashScreenPresentation(){
        // Get a refernce to LaunchScreen.storyboard
        let launchStoryBoard = UIStoryboard.init(name: "LaunchScreen", bundle: nil)
        // Get the splash screen controller
        let splashController = launchStoryBoard.instantiateViewController(withIdentifier: "splashController")
        // Assign it to rootViewController
        self.window?.rootViewController = splashController
        self.window?.makeKeyAndVisible()
        // Setup a timer to remove it after n seconds
        Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(dismissSplashController), userInfo: nil, repeats: false)
    }
    

2.

@objc private func dismissSplashController() {
    // Get a refernce to Main.storyboard
    let mainStoryBoard = UIStoryboard.init(name: "Main", bundle: nil)
    // Get initial viewController
    let initController = mainStoryBoard.instantiateViewController(withIdentifier: "initController")
    // Assign it to rootViewController
    self.window?.rootViewController = initController
    self.window?.makeKeyAndVisible()
}

Now you call

 self.extendSplashScreenPresentation()

in didFinishLaunchingWithOptions.

You are set to go...

Ehab Saifan
  • 290
  • 2
  • 13
5

This worked for me in Xcode 6.3.2, Swift 1.2 :

import UIKit

class ViewController: UIViewController
{
    var splashScreen:UIImageView!

    override func viewDidLoad()
    {
        super.viewDidLoad()

        self.splashScreen = UIImageView(frame: self.view.frame)
        self.splashScreen.image = UIImage(named: "Default.png")
        self.view.addSubview(self.splashScreen)

        var removeSplashScreen = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: "removeSP", userInfo: nil, repeats: false)
    }

    func removeSP()
    {
        println(" REMOVE SP")
        self.splashScreen.removeFromSuperview()
    }

    override func didReceiveMemoryWarning()
    {
        super.didReceiveMemoryWarning()
    }
}

ViewController is the first app VC that is being loaded.

Martin Thompson
  • 16,395
  • 1
  • 38
  • 56
MB_iOSDeveloper
  • 4,178
  • 4
  • 24
  • 36
5

In Swift 4.2

For Delay 1 second after default launch time...

Thread.sleep(forTimeInterval: 1)
srsstyle
  • 99
  • 1
  • 9
5

This tutorial displays splash screen for 2 seconds. You can easily change it to suit your needs.

- (void)showSplash {
  UIViewController *modalViewController = [[UIViewController alloc] init];
  modalViewController.view = modelView;
  [self presentModalViewController:modalViewController animated:NO];
  [self performSelector:@selector(hideSplash) withObject:nil afterDelay:yourDelay];
}
gotnull
  • 26,454
  • 22
  • 137
  • 203
visakh7
  • 26,380
  • 8
  • 55
  • 69
4

Use following line in didFinishLaunchingWithOptions: delegate method:

[NSThread sleepForTimeInterval:5.0];

It will stop splash screen for 5.0 seconds.

Bhavin Bhadani
  • 22,224
  • 10
  • 78
  • 108
Himanshu Mahajan
  • 4,779
  • 2
  • 36
  • 29
  • 12
    Delay the startup of your app may result in your app being killed by the watchdog for taking to long to load. So never ever delay startup. – rckoenes Oct 15 '13 at 14:42
  • In Swift in didFinishLaunchingWithOptions: delegate method of AppDelegate Class add this code: Thread.sleep(forTimeInterval: 5.0) – Vinathy nvr Oct 03 '17 at 10:48
  • A comment from 2018. I need a 2 secs delay, I have a launch screen coming from the launchimages from xcassets and not from a xib or storyboard, so it's quite a hassle to show a screen that serves as an "extended launch screen", because you'll have to determine the kind of the phone and your exact display should match the launch image shown. So I guess this won't be so bad if I just need a 1 second of sleep. Just.... 1 second. – Glenn Posadas Jun 26 '18 at 17:54
4

Swift 2.0:

1)

//  AppDelegate.swift

import UIKit
import Foundation

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate {

 var window: UIWindow?
 var splashTimer:NSTimer?
 var splashImageView:UIImageView?

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

  window = UIApplication.sharedApplication().delegate!.window!

  let splashImage: UIImage = UIImage(named: "ic_120x120.png")!
  splashImageView = UIImageView(image: splashImage)
  splashImageView!.frame = CGRectMake(0, 0, (window?.frame.width)!, (window?.frame.height)!)

  window!.addSubview(splashImageView!)
  window!.makeKeyAndVisible()

  //Adding splash Image as UIWindow's subview.
  window!.bringSubviewToFront(window!.subviews[0])

  // Here specify the timer.
  splashTimer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "splashTimerForLoadingScreen", userInfo: nil, repeats: true)

  return true
 }
 func splashTimerForLoadingScreen() {
  splashImageView!.removeFromSuperview()
  splashTimer!.invalidate()
 }

2)

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

  NSThread.sleepForTimeInterval(9)

  OR

  sleep(9)

  return true
 }

3) Using root view controller concept:

//  AppDelegate.swift

import UIKit
import Foundation

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate {

 var window: UIWindow?
 var splashTimer:NSTimer?
 var storyboard:UIStoryboard?

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

  window =  UIWindow(frame: UIScreen.mainScreen().bounds)
  window?.makeKeyAndVisible()

  storyboard = UIStoryboard(name: "Main", bundle: nil)

  //Here set the splashScreen VC
  let rootController = storyboard!.instantiateViewControllerWithIdentifier("secondVCID")

  if let window = self.window {
   window.rootViewController = rootController
  }

  //Set Timer
  splashTimer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "splashTimerCrossedTimeLimit", userInfo: nil, repeats: true)

  return true
 }
 func splashTimerCrossedTimeLimit(){

  //Here change the root controller
  let rootController = storyboard!.instantiateViewControllerWithIdentifier("firstVCID")
  if let window = self.window {
   window.rootViewController = rootController
  }
  splashTimer?.invalidate()
 }
Alvin George
  • 14,148
  • 92
  • 64
3

You can use following code:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ 
    NSMutableString *path = [[NSMutableString alloc]init];
    [path setString:[[NSBundle mainBundle] resourcePath]];
    [path setString:[path stringByAppendingPathComponent:@"Default.png"]];
    UIImage *image = [[UIImage alloc] initWithContentsOfFile:path];
    [path release];

    UIImageView *imageView=[[UIImageView alloc]initWithImage:image];
    imageView.frame=CGRectMake(0, 0, 320, 480);
    imageView.tag = 2;
    [window addSubview:imageView];
    [window makeKeyAndVisible];

    // Here specify the time limit.
    timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(timerForLoadingScreen) userInfo:nil repeats:YES];
}

-(void)timerForLoadingScreen
{
    [timer invalidate];
    if ([window viewWithTag:2]!=nil) 
    {
        [[window viewWithTag:2]removeFromSuperview];
    }

    // Your any other initialization code that you wish to have in didFinishLaunchingWithOptions
}
gotnull
  • 26,454
  • 22
  • 137
  • 203
Ravin
  • 8,544
  • 3
  • 20
  • 19
1

Write sleep(5.0)

in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions for 5 seconds splash screen will be displayed

Dhara
  • 4,093
  • 2
  • 36
  • 69
1

This works...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Load Splash View Controller first
    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"Splash"];
    self.window.rootViewController = viewController;
    [self.window makeKeyAndVisible];

    // Load other stuff that requires time

    // Now load the main View Controller that you want
}
1

1.Add a another view controller in “didFinishLaunchingWithOptions”

 UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

UINavigationController *homeNav = [storyboard instantiateViewControllerWithIdentifier:@"NavigationControllerView"];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"SplashViewController"];

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = homeNav;
[self.window makeKeyAndVisible];

[(UINavigationController *)self.window.rootViewController pushViewController:viewController animated:NO];
}

2.In view did load of SplashView Controller

  [self performSelector:@selector(removeSplashScreenAddViewController) withObject:nil afterDelay:2.0];

3.In removeSplashScreenAddViewController method you can add your main view controller for eg.-

- (void) removeSplashScreenAddViewController {`  UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UINavigationController *homeNav = [storyboard instantiateViewControllerWithIdentifier:@"HomeNav"];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:viewControllerName];

UIWindow *window =  [StaticHelper mainWindow];
window.rootViewController = homeNav;
[window makeKeyAndVisible];

[(UINavigationController *)window.rootViewController pushViewController:viewController animated:NO];`}
shweta sharma
  • 11
  • 1
  • 3
1

In swift 4.0
For Delay of 1 second after default launch time...

RunLoop.current.run(until: Date(timeIntervalSinceNow : 1.0))
Hardik Trivedi
  • 613
  • 7
  • 10
1

The simplest way to achieve this is to creat an UIImageView with "Default.png" on the top of your first ViewController's UIView.

And add an Timer to remove the UIImageView after seconds you expected.

gotnull
  • 26,454
  • 22
  • 137
  • 203
xhan
  • 6,057
  • 4
  • 33
  • 47
1

Put your default.png in a UIImageView full screen as a subview on the top of your main view thus covering your other UI. Set a timer to remove it after x seconds (possibly with effects) now showing your application.

Tomasz Stanczak
  • 12,796
  • 1
  • 30
  • 32
0

You can simple specify number of seconds to sleep in the AppDelegate didFinishLaunchingWithOptions method.

Or alternatively use another ImageView to customize the splash screen.

See details for the latter at the following link by me:

Splash Screen Problem

Community
  • 1
  • 1
John Doe
  • 2,173
  • 1
  • 21
  • 12
  • 2
    Delay the startup of your app may result in your app being killed by the watchdog for taking to long to load. So never ever delay startup. – rckoenes Feb 13 '15 at 13:49
0

Just go on project name. then Right Click/properties/Application Tab. Find "view Application Events" near Slash form combobox. copy this code in myApplication Class :

        Private Sub MyApplication_Startup(sender As Object, e As StartupEventArgs) Handles Me.Startup
              System.Threading.Thread.Sleep(3000) ' or other time
        End Sub
rptwsthi
  • 10,094
  • 10
  • 68
  • 109
Sharif Lotfi
  • 544
  • 6
  • 13
0

You can create your own view and display it when application starts and hide it with timer. Please avoid delaying app start as its bad idea

Umair Khalid
  • 2,259
  • 1
  • 21
  • 28
0

The simplest solution here is to add sleep() to didFinishLaunchingWithOptions method in your AppDelegate class.

Swift 4:

sleep(1)
  • delays the LaunchScreen by 1 second.

If you wanna do something fancier you can also extend the current RunLoop in the same method:

Swift 4:

RunLoop.current.run(until: Date(timeIntervalSinceNow: 1))
Dick Thunder
  • 378
  • 3
  • 17
  • Good solutions - but what is the difference between them ??? (on a more in-depth point of view) ? – iKK Aug 25 '18 at 09:17