Related
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.
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.
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];
}
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]];
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)
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)
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.
First in LaunchingScreen.storyboard give your controller a StoryBoard identifier let's say "splashController"
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:
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...
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];
}
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.
In Swift 4.2
For Delay 1 second after default launch time...
Thread.sleep(forTimeInterval: 1)
Use following line in didFinishLaunchingWithOptions: delegate method:
[NSThread sleepForTimeInterval:5.0];
It will stop splash screen for 5.0 seconds.
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()
}
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
}
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.
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.
Write sleep(5.0)
in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions for 5 seconds splash screen will be displayed
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.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];`}
In swift 4.0
For Delay of 1 second after default launch time...
RunLoop.current.run(until: Date(timeIntervalSinceNow : 1.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
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
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
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))
I am trying to change the root view controller from the app delegate's didFinishLaunchingWithOptions, depending on whether the user is logged in or not. Once I get past this condition, I am using the following code to change root view controllers:
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SWRevealViewController") as! SWRevealViewController
self.window?.makeKeyAndVisible()
However, when I launch the app (with a valid logged in user) the simulator first shows the log in screen (old root view controller) for a second, then the screen goes black for about 30 seconds to a minute, before finally showing the desired view controller.
The view controller structure in storyboard is as follows:
SWRevealViewController -> Navigation Controller -> Desired View Controller (new root)
The reason for beginning with SWRevealViewController is because the slide menu is lost otherwise.
Any ideas of what might be going on?
I found a way to produce a similar result to the one I desired. It involves not changing the root view controller at all, and having it present an "artificial root view controller" after launch:
if let currentRoot = self.window?.rootViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let artificialRoot = storyboard.instantiateViewController(withIdentifier: "SWRevealViewController")
currentRoot.present(artificialRoot, animated: false, completion: nil)
}
Although not ideal, the results of this implementation are by far better than the implementation in the question description.
Here is an example, that works for me, just make your loginViewControllers to be a stack of UINavigationController, not related to SWRevealController. It is easy workaround.
self.window = UIWindow(frame: UIScreen.main.bounds)
if User.shared.firstLaunch {
let navigationVC = Storyboard.inital.instantiateViewController(withIdentifier: "firstLaunchNC") as! UINavigationController
self.window?.rootViewController = navigationVC
} else if User.shared.token == "" {
let navigationVC = Storyboard.inital.instantiateViewController(withIdentifier: "initialVC") as! UINavigationController
self.window?.rootViewController = navigationVC
} else {
self.registerForPushNotifications(application: UIApplication.shared)
User.shared.refreshToken()
let revealController = Storyboard.main.instantiateViewController(withIdentifier: "revealViewController") as! SWRevealViewController
self.window?.rootViewController = revealController
}
self.window?.makeKeyAndVisible()
return true
try this:
let viewController = ViewController()
let navigationController = UINavigationController(rootViewController: viewController)
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
try this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UITabBarController *tbc = [storyboard instantiateViewControllerWithIdentifier:#"TabBarController"];
tbc.selectedIndex=[singleton getSelectedTabIndex];
// tbc.selectedIndex=0;
//self.window.rootViewController = tbc;
[self.window setRootViewController:tbc];
[UIView transitionWithView:self.window duration:0.3 options:UIViewAnimationOptionTransitionCrossDissolve animations:nil
completion:nil];
If This not work..Please check your initial Controller ...In Which Never try Load NSAtrributedString
NSAttributedString *attrStr = [[NSAttributedString alloc]
initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding]
options:#{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: #(NSUTF8StringEncoding)}
documentAttributes:nil
error:nil];
Note:-- Black Screen Apear When Initial Controller ViewDidLoad Take Some time to load UIview into Memory due some Lazy UI loading Assests are done in ViewDidLoad...
Try heavy load view cide into ViewWillApear or ViewDidApear ....
I have 5 tabs and want to go to a specific tab when user select a certain Quick Action.
However, I've tried using notification center, referencing the master viewcontroller and referencing the tab in app delegate but none seems to work. The tabbar.selectedIndex method does get called but for some reasons the tab isn't changing when using quick action.
#available(iOS 9.0, *)
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
let revealVC = self.window!.rootViewController as! SWRevealViewController
let tabVC = revealVC.childViewControllers[1] as! UITabBarController
let navVC = tabVC.viewControllers![0] as! UINavigationController
let shopVC = navVC.viewControllers[0] as! BrowseVC
switch shortcutItem.type {
case "com.modesens.search" :
tabVC.selectedIndex = 0
//referencing method to go to tab in base view controller also doesn't work...
//shopVC.goToSelectTab (0)
completionHandler(true)
//notification center method gets called but tab actually doesn't change
//NSNotificationCenter.defaultCenter().postNotificationName("goToTab", object: nil, userInfo: ["tabIndex":0])
default:
print("no work")
}
completionHandler(false)
}
revealVC is parent, tabVC is child of revealVC, then navVC is child of tab.
Again, I've tried using notificationCenter and referencing the shopVC, then calling this method:
Recently, I have implemented home screen quick action with SWRevealVC library. So, I'm very glad to tell you how to solve this issue.
1) create SWRevealVC programmatically(not in the storyboard)
If you have 5 tabs and you want to move another tab with quick action,
you should change frontVC of SWRevealVC dynamically to response to quick action.
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window = window;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController *frontViewController = [storyboard instantiateViewControllerWithIdentifier:#"mainNaviVC"];
SideMenuViewController *rearViewController = [storyboard instantiateViewControllerWithIdentifier:#"sideMenuVC"];
SWRevealViewController *mainRevealController = [[SWRevealViewController alloc]
initWithRearViewController:rearViewController
frontViewController:frontViewController];
self.window.rootViewController = mainRevealController;
2) implement logic in the didFinishLaunchingWithOptions method
As apple documented mentioned, it is the best place for quick action logic in didFinishLaunchingWithOptions if you want to change first page.
In my case, performActionForShortcutItem is only called to deal with app's background.(you should return NO in didFinishLaunchingWithOptions to handle quick action in didFinishLaunchingWithOptions)
if ([shortcutItem.type isEqualToString:shortcutAroundStop]) {
handled = YES;
UINavigationController *frontViewController = [storyboard instantiateViewControllerWithIdentifier:#"naviStopAroundVC"];
SideMenuViewController *rearViewController = [storyboard instantiateViewControllerWithIdentifier:#"sideMenuVC"];
SWRevealViewController *mainRevealController = [[SWRevealViewController alloc]
initWithRearViewController:rearViewController
frontViewController:frontViewController];
self.window.rootViewController = mainRevealController;
[self.window makeKeyAndVisible];
}
And I give a sample project what I make(objective-c) for you. I hope it will solve your problem.
https://github.com/dakeshi/3D_Touch_HomeQuickAction
I have created my project using Storyboards. The root ViewController lies inside a Storyboard, I have not written a single code in the appDelegate.
Now I want to show a tour of my app, so I want to change the root ViewController from Tab Bar to my TourVC and when the tour of the app is finished , I want to again switch back my root ViewController to Tab Bar.
So I looked up online and followed the following points
1) Remove Storyboards from app.plist file,
2) Uncheck option "isInitialViewController" from Storyboards which is checked in case of Tab Bar controller because its a root ViewController,
3) Add this code in appDelegate.m file.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
ProductTourViewController *PT = [[ProductTourViewController alloc] initWithNibName:#"ProductTourViewController" bundle:nil];
self.window.rootViewController = PT;
[self.window makeKeyAndVisible];
return YES;
But my app crashes with this error log,
[ProductTourViewController selectedViewController]: unrecognized selector sent to instance 0x1766a9e0
And also I get a warning,
Unsupported Configuration: Scene is unreachable due to lack of entry points and does not have an identifier for runtime access via -instantiateViewControllerWithIdentifier:.
Objective-C:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UITabBarController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:#"tabBarcontroller"];
[[UIApplication sharedApplication].keyWindow setRootViewController:rootViewController];
Swift :
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = mainStoryboard.instantiateViewControllerWithIdentifier("tabBarcontroller") as UITabBarController
UIApplication.sharedApplication().keyWindow?.rootViewController = viewController;
Swift 3:
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = mainStoryboard.instantiateViewController(withIdentifier: "tabBarcontroller") as! UITabBarController
UIApplication.shared.keyWindow?.rootViewController = viewController
Swift 5:
let viewController = mainStoryboard.instantiateViewController(withIdentifier: "tabBarcontroller") as! UITabBarController
UIApplication.shared.windows.first?.rootViewController = viewController
UIApplication.shared.windows.first?.makeKeyAndVisible()
Or simply like this:
let viewController = mainStoryboard.instantiateViewController(withIdentifier: "tabBarcontroller") as! UITabBarController
self.view.window?.rootViewController = viewController
self.view.window?.makeKeyAndVisible()
Both works fine!
Set storyboard ID for your class in your main storyboard.
UIStoryboard *MainStoryboard = [UIStoryboard storyboardWithName:#"Main"
bundle: nil];
UINavigationController *controller = (UINavigationController*)[MainStoryboard
instantiateViewControllerWithIdentifier: #"RootNavigationController"];
LoginViewController *login=[MainStoryboard instantiateViewControllerWithIdentifier:#"LoginViewController"];
[controller setViewControllers:[NSArray arrayWithObject:login] animated:YES];
self.window.rootViewController=controller;
In swift we can implement it is as following
let storyboard = UIStoryboard(name: "StartingPage", bundle: NSBundle.mainBundle())
let loginView: SignInVC = storyboard.instantiateViewControllerWithIdentifier("SignInVC") as! SignInVC
UIApplication.sharedApplication().keyWindow?.rootViewController = loginView
I use simple this:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"NameOfStoryBoard" bundle:nil];
UITabBarController *rootViewController = [sb instantiateViewControllerWithIdentifier:#"NameOfTabBarController"];
[[UIApplication sharedApplication].keyWindow setRootViewController:rootViewController];
Just to add to Sunny Shah's answer, this is the Swift 3 version of it:
let mainStoryBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController: UIViewController = mainStoryBoard.instantiateViewController(withIdentifier: "MainTabBarController") as! UITabBarController
UIApplication.shared.keyWindow?.rootViewController = viewController
Swift 3 code:
Use below in didFinishLaunchingWithOptions Appdelegate function.
Replace "HomeViewController" with ViewController you want to set as Root ViewController on app launch.
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "HomeViewController")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
return true
Swift 5 + Xcode 11:
Make like this:
let viewController = mainStoryboard.instantiateViewController(withIdentifier: "tabBarcontroller") as! UITabBarController
UIApplication.shared.windows.first?.rootViewController = viewController
UIApplication.shared.windows.first?.makeKeyAndVisible()
Or like this:
let viewController = mainStoryboard.instantiateViewController(withIdentifier: "tabBarcontroller") as! UITabBarController
self.view.window?.rootViewController = viewController
self.view.window?.makeKeyAndVisible()
Both works fine!
Objective c
step 1: remove main story board from info.plist
step 2: add storyboard id to your view controller in your interface builder
step 3: add the following code to application did finish method in app delegate
self.window = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];
//set main story board
if( condition){
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"StoryboardName1" bundle:nil];
UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:#"ViewController1"];
[[UIApplication sharedApplication].keyWindow setRootViewController:rootViewController];
[self window].rootViewController = rootViewController;
[self.window makeKeyAndVisible];
}else{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"StoryboardName2" bundle:nil];
UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:#"ViewController2"];
[[UIApplication sharedApplication].keyWindow setRootViewController:rootViewController];
[self window].rootViewController = rootViewController;
[self.window makeKeyAndVisible];
}
This is an old article, but I will reply.
I do not recommend the following code.
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = mainStoryboard.instantiateViewController(withIdentifier: "tabBarcontroller") as! UITabBarController
UIApplication.shared.keyWindow?.rootViewController = viewController
Because you are creating two instances.
I recommend writing the following code in the appropriate ViewController.
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = self
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.
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.
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];
}
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]];
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)
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)
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.
First in LaunchingScreen.storyboard give your controller a StoryBoard identifier let's say "splashController"
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:
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...
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];
}
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.
In Swift 4.2
For Delay 1 second after default launch time...
Thread.sleep(forTimeInterval: 1)
Use following line in didFinishLaunchingWithOptions: delegate method:
[NSThread sleepForTimeInterval:5.0];
It will stop splash screen for 5.0 seconds.
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()
}
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
}
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.
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.
Write sleep(5.0)
in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions for 5 seconds splash screen will be displayed
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.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];`}
In swift 4.0
For Delay of 1 second after default launch time...
RunLoop.current.run(until: Date(timeIntervalSinceNow : 1.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
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
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
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))