Comment définir par programme le InitialViewController
pour un Storyboard? Je veux ouvrir mon storyboard à une vue différente en fonction de certaines conditions qui peuvent varier d'un lancement à l'autre.
Comment définir par programme le InitialViewController
pour un Storyboard? Je veux ouvrir mon storyboard à une vue différente en fonction de certaines conditions qui peuvent varier d'un lancement à l'autre.
Réponses:
Comment sans contrôleur de vue initial factice
Assurez-vous que tous les contrôleurs de vue initiaux ont un ID de storyboard.
Dans le storyboard, décochez l'attribut "Is initial View Controller" du premier contrôleur de vue.
Si vous exécutez votre application à ce stade, vous lirez:
Failed to instantiate the default view controller for UIMainStoryboardFile 'MainStoryboard' - perhaps the designated entry point is not set?
Et vous remarquerez que votre propriété de fenêtre dans le délégué d'application est désormais nulle.
Dans le paramètre de l'application, accédez à votre cible et à l' Info
onglet. Là, la valeur de Main storyboard file base name
. Sous l' General
onglet, effacez la valeur de Main Interface
. Cela supprimera l'avertissement.
Créez la fenêtre et le contrôleur de vue initial souhaité dans la application:didFinishLaunchingWithOptions:
méthode du délégué d'application :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *viewController = // determine the initial view controller here and instantiate it with [storyboard instantiateViewControllerWithIdentifier:<storyboard id>];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
return YES;
}
didFinishLaunchingWithOptions
est appelé lorsque l'application est lancée dans un nouveau processus. Si vous accédez à l'écran d'accueil et revenez à l'application, cette méthode ne sera plus invoquée. (À moins que iOS ne s'arrête en raison de contraintes de mémoire.) Essayez d'arrêter l'application et de la relancer à partir de votre IDE. Si le problème persiste, postez le problème à SO et je serai heureux de vous aider, ami.
self.window = UIWindow(frame: UIScreen.mainScreen().bounds) var storyboard = UIStoryboard(name: "Main", bundle: nil) var viewController: UIViewController = // self.window!.rootViewController = viewController self.window!.makeKeyAndVisible()
Pour tous les amoureux de Swift , voici la réponse de @Travis traduite en SWIFT :
Faites ce que @Travis a expliqué avant le code Objective C. Ensuite,
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var exampleViewController: ExampleViewController = mainStoryboard.instantiateViewControllerWithIdentifier("ExampleController") as! ExampleViewController
self.window?.rootViewController = exampleViewController
self.window?.makeKeyAndVisible()
return true
}
le ExampleViewController
serait le nouveau contrôleur de vue initial que vous souhaitez afficher.
Les étapes expliquées:
Profitez-en et bonne programmation!
Vous pouvez définir par programme rootViewController de la fenêtre clé dans (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
par exemple:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (shouldShowAnotherViewControllerAsRoot) {
UIStoryboard *storyboard = self.window.rootViewController.storyboard;
UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:@"rootNavigationController"];
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
}
return YES;
}
init()
/ deinit()
, mais sans exécuter viewDidLoad()
ou initialiser correctement IBOutlet
-s. Assurez-vous que votre code est prêt pour cela.
Swift 3: mise à jour du code de @ victor-sigler
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
// Assuming your storyboard is named "Main"
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
// Add code here (e.g. if/else) to determine which view controller class (chooseViewControllerA or chooseViewControllerB) and storyboard ID (chooseStoryboardA or chooseStoryboardB) to send the user to
if(condition){
let initialViewController: chooseViewControllerA = mainStoryboard.instantiateViewController(withIdentifier: "chooseStoryboardA") as! chooseViewControllerA
self.window?.rootViewController = initialViewController
)
}else{
let initialViewController: chooseViewControllerB = mainStoryboard.instantiateViewController(withIdentifier: "chooseStoryboardB") as! chooseViewControllerB
self.window?.rootViewController = initialViewController
)
self.window?.makeKeyAndVisible(
return true
}
Vous pouvez définir Navigation rootviewcontroller comme contrôleur de vue principal. Cette idée peut être utilisée pour la connexion automatique selon les exigences de l'application.
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
UIViewController viewController = (HomeController*)[mainStoryboard instantiateViewControllerWithIdentifier: @"HomeController"];
UINavigationController navController = [[UINavigationController alloc] initWithRootViewController:viewController];
self.window.rootViewController = navController;
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
// do stuff for iOS 7 and newer
navController.navigationBar.barTintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0];
navController.navigationItem.leftBarButtonItem.tintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0];
navController.navigationBar.tintColor = [UIColor whiteColor];
navController.navigationItem.titleView.tintColor = [UIColor whiteColor];
NSDictionary *titleAttributes =@{
NSFontAttributeName :[UIFont fontWithName:@"Helvetica-Bold" size:14.0],
NSForegroundColorAttributeName : [UIColor whiteColor]
};
navController.navigationBar.titleTextAttributes = titleAttributes;
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
else {
// do stuff for older versions than iOS 7
navController.navigationBar.tintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0];
navController.navigationItem.titleView.tintColor = [UIColor whiteColor];
}
[self.window makeKeyAndVisible];
Pour les utilisateurs de StoryboardSegue
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
// Go to Login Screen of story board with Identifier name : LoginViewController_Identifier
LoginViewController *loginViewController = (LoginViewController*)[mainStoryboard instantiateViewControllerWithIdentifier:@“LoginViewController_Identifier”];
navigationController = [[UINavigationController alloc] initWithRootViewController:testViewController];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
// Go To Main screen if you are already Logged In Just check your saving credential here
if([SavedpreferenceForLogin] > 0){
[loginViewController performSegueWithIdentifier:@"mainview_action" sender:nil];
}
Merci
Ouvrez le tableau principal, sélectionnez d'abord la vue que vous souhaitez démarrer, puis ouvrez Utilitaires -> Attributs. Sous le "View Controller", vous voyez le bouton radio "Is initial View Controller". Sélectionnez-le.
--- À la question révisée:
Peut-être pouvez-vous essayer ceci: écrivez une méthode dans la section ViewDidLoad de votre vue initiale et lorsque la méthode s'exécute au lancement de l'application, la méthode déclenche une transition vers une autre vue.
SWIFT 5
Si vous n'avez pas de ViewController défini comme ViewController initial dans le storyboard, vous devez faire 2 choses:
Enfin, vous pouvez maintenant ajouter votre code dans SceneDelegate:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// Make sure you set an Storyboard ID for the view controller you want to instantiate
window?.rootViewController = storyboard.instantiateViewController(withIdentifier: identifier)
window?.makeKeyAndVisible()
}
Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set
avertissement que j'avais après avoir décidé d'instancier mon VC initial dans le code. Un point important, lorsque @ rs7 dit "supprimer le champ du nom du storyboard", cela signifie toute la ligne du plist, pas seulement le contenu du champ lui-même.
Vous pouvez définir à l' initial view controller
aide d'Interface Builder ainsi que par programme.
Ci-dessous, l'approche utilisée pour la programmation.
Objectif c :
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"HomeViewController"]; // <storyboard id>
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
return YES;
Rapide :
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var objMainViewController: MainViewController = mainStoryboard.instantiateViewControllerWithIdentifier("MainController") as! MainViewController
self.window?.rootViewController = objMainViewController
self.window?.makeKeyAndVisible()
return true
J'ai créé une classe de routage pour gérer la navigation dynamique et garder la classe AppDelegate propre, j'espère que cela aidera d'autres aussi.
//
// Routing.swift
//
//
// Created by Varun Naharia on 02/02/17.
// Copyright © 2017 TechNaharia. All rights reserved.
//
import Foundation
import UIKit
import CoreLocation
class Routing {
class func decideInitialViewController(window:UIWindow){
let userDefaults = UserDefaults.standard
if((Routing.getUserDefault("isFirstRun")) == nil)
{
Routing.setAnimatedAsInitialViewContoller(window: window)
}
else if((userDefaults.object(forKey: "User")) != nil)
{
Routing.setHomeAsInitialViewContoller(window: window)
}
else
{
Routing.setLoginAsInitialViewContoller(window: window)
}
}
class func setAnimatedAsInitialViewContoller(window:UIWindow) {
Routing.setUserDefault("Yes", KeyToSave: "isFirstRun")
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let animatedViewController: AnimatedViewController = mainStoryboard.instantiateViewController(withIdentifier: "AnimatedViewController") as! AnimatedViewController
window.rootViewController = animatedViewController
window.makeKeyAndVisible()
}
class func setHomeAsInitialViewContoller(window:UIWindow) {
let userDefaults = UserDefaults.standard
let decoded = userDefaults.object(forKey: "User") as! Data
User.currentUser = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! User
if(User.currentUser.userId != nil && User.currentUser.userId != "")
{
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let homeViewController: HomeViewController = mainStoryboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
let loginViewController: UINavigationController = mainStoryboard.instantiateViewController(withIdentifier: "LoginNavigationViewController") as! UINavigationController
loginViewController.viewControllers.append(homeViewController)
window.rootViewController = loginViewController
}
window.makeKeyAndVisible()
}
class func setLoginAsInitialViewContoller(window:UIWindow) {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let loginViewController: UINavigationController = mainStoryboard.instantiateViewController(withIdentifier: "LoginNavigationViewController") as! UINavigationController
window.rootViewController = loginViewController
window.makeKeyAndVisible()
}
class func setUserDefault(_ ObjectToSave : Any? , KeyToSave : String)
{
let defaults = UserDefaults.standard
if (ObjectToSave != nil)
{
defaults.set(ObjectToSave, forKey: KeyToSave)
}
UserDefaults.standard.synchronize()
}
class func getUserDefault(_ KeyToReturnValye : String) -> Any?
{
let defaults = UserDefaults.standard
if let name = defaults.value(forKey: KeyToReturnValye)
{
return name as Any
}
return nil
}
class func removetUserDefault(_ KeyToRemove : String)
{
let defaults = UserDefaults.standard
defaults.removeObject(forKey: KeyToRemove)
UserDefaults.standard.synchronize()
}
}
Et dans votre AppDelegate, appelez cela
self.window = UIWindow(frame: UIScreen.main.bounds)
Routing.decideInitialViewController(window: self.window!)
Une autre solution avec l'utilisation de Swift 3 et Swift 4 pour éviter le lancer forcé est comme ceci
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewController") as? YourViewController else {
return false
}
self.window?.rootViewController = viewController
self.window?.makeKeyAndVisible()
return true
}
Et ci-dessous utilise avec UINavigationController
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewController") as? YourViewController else {
return false
}
let navigationController = UINavigationController(rootViewController: viewController)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
return true
}
Dans, AppDelegate.swift
vous pouvez ajouter le code suivant:
let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "YourViewController_StorboardID")
self.window?.rootViewController = vc
self.window?.makeKeyAndVisible()
Bien sûr, vous devez implémenter votre logique, en fonction des critères que vous choisirez un contrôleur de vue approprié.
N'oubliez pas non plus d'ajouter une identité (sélectionnez storyboard -> Controller Scene -> Afficher l'inspecteur d'identité -> assigner StorboardID).
RÉPONSE MISE À JOUR pour iOS 13 et délégué de scène:
assurez-vous que dans votre fichier info.plist, allez dans Manifeste de scène d'application -> Configuration de scène -> Rôle de session d'application -> Élément 0 et supprimez également la référence au storyboard principal. Sinon, vous obtiendrez le même avertissement concernant l'échec de l'instanciation du storyboard.
Déplacez également le code du délégué d'application vers la scène de la méthode de délégué de scène (_: willConnectTo: options :), car c'est là que les événements du cycle de vie sont désormais traités.
Il y a quelques jours, j'ai rencontré la même situation. Une astuce très simple a résolu ce problème. J'ai mis mon contrôleur de vue initial caché avant le lancement2. Si le contrôleur de vue initial est le bon contrôleur, il est défini sur visible dans viewDidLoad. Sinon, une séquence est effectuée vers le contrôleur de vue souhaité. Cela fonctionne parfaitement dans iOS 6.1 et supérieur. Je suis sûr que cela fonctionne sur les versions antérieures d'iOS.
Merci d'avoir modifié cela comme suit dans AppDelegate:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//Some code to check value of pins
if pins! == "Verified"{
print(pins)
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "HomePage", bundle: nil)
let exampleViewController: UINavigationController = mainStoryboard.instantiateViewControllerWithIdentifier("SBHP") as! UINavigationController
self.window?.rootViewController = exampleViewController
self.window?.makeKeyAndVisible()
}else{
print(pins)
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let exampleViewController: UINavigationController = mainStoryboard.instantiateViewControllerWithIdentifier("SBUser") as! UINavigationController
self.window?.rootViewController = exampleViewController
self.window?.makeKeyAndVisible()
}
Solution simple trouvée - pas besoin de supprimer la "vérification initiale du contrôleur de vue" du storyboard et de modifier l'onglet Info du projet et de l'utiliser makeKeyAndVisible
, il suffit de placer
self.window.rootViewController = rootVC;
dans
- (BOOL) application:didFinishLaunchingWithOptions:
rootVC
de instantiateViewControllerWithIdentifier
, correct?
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = mainStoryboard.instantiateViewController(withIdentifier: "storyBoardid") as! ViewController
let navigationController = UINavigationController(rootViewController: vc)
UIApplication.shared.delegate.window?.rootViewController = navigationController
Une autre façon est de présenter viewController,
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = mainStoryboard.instantiateViewController(withIdentifier: "storyBoardid") as! ViewController
self.present(vc,animated:true,completion:nil)
Vous devez d'abord créer un objet de votre storyboard, puis changer de racine (si nécessaire), puis vous prendrez la référence d'un contrôleur de vue particulier qui est poussé le contrôleur de vue actuel (si vous changez de racine) sinon c'est juste un nouveau contrôleur de vue qui peut vous
Swift 4, Xcode 9
dans le fichier AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let firstVC = storyboard.instantiateViewController(withIdentifier: "firstViewController") as! firstViewController
self.window?.rootViewController = firstVC
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if (PreferenceHelper.getAccessToken() != "") {
let initialViewController = storyboard.instantiateViewController(withIdentifier: "your View Controller Identifier")
self.window?.rootViewController = initialViewController
} else {
let initialViewController = storyboard.instantiateViewController(withIdentifier: "your View Controller identifier")
self.window?.rootViewController = initialViewController
}
self.window?.makeKeyAndVisible()
return true
}
/*
use your view Controller identifier must use it doubles quotes**strong text**
Swift 5 ou supérieur # rend le contrôleur de vue d'itinéraire par ce code simple. Si vous utilisez xcode 11 ou supérieur, initialisez d'abord var window: UIWindow?
dans AppDelegate
let rootVC = mainStoryboard.instantiateViewController(withIdentifier: "YOURCONTROLLER") as! YOURCONTROLLER
navigationController.setNavigationBarHidden(true, animated: true)
UIApplication.shared.windows.first?.rootViewController = UINavigationController.init(rootViewController: rootVC)
UIApplication.shared.windows.first?.makeKeyAndVisible()
Si vous préférez ne pas modifier applicationDidFinish, vous pouvez effectuer l'astuce suivante:
Définissez le contrôleur de navigation comme contrôleur de vue initial et affectez-lui une classe personnalisée «MyNavigationController». Ensuite, vous pouvez modifier son contrôleur de vue racine pendant viewDidLoad - il remplacera le contrôleur de vue racine que vous avez défini dans votre storyboard.
class MyNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
if !isLoggedIn() {
viewControllers = [R.storyboard.authentication.loginView()!]
}
}
private func isLoggedIn() -> Bool {
return false
}
}
Sélectionnez le contrôleur de vue que vous souhaitez ouvrir en premier et accédez à l'inspecteur d'attributs. Allez à la scène initiale et cochez l'option du contrôleur de vue initiale.
Maintenant, ce sera votre contrôleur de vue initial qui s'ouvrira en premier lors du lancement de l'application.