Wie stelle ich das programmgesteuert InitialViewController
für ein Storyboard ein? Ich möchte mein Storyboard in einer anderen Ansicht öffnen, abhängig von einer Bedingung, die von Start zu Start variieren kann.
Wie stelle ich das programmgesteuert InitialViewController
für ein Storyboard ein? Ich möchte mein Storyboard in einer anderen Ansicht öffnen, abhängig von einer Bedingung, die von Start zu Start variieren kann.
Antworten:
Wie ohne einen Dummy-Erstansichts-Controller
Stellen Sie sicher, dass alle Controller für die Erstansicht eine Storyboard-ID haben.
Deaktivieren Sie im Storyboard das Attribut "Ist der anfängliche Ansichts-Controller" im ersten Ansichts-Controller.
Wenn Sie Ihre App zu diesem Zeitpunkt ausführen, lesen Sie:
Failed to instantiate the default view controller for UIMainStoryboardFile 'MainStoryboard' - perhaps the designated entry point is not set?
Und Sie werden feststellen, dass Ihre Fenstereigenschaft im App-Delegaten jetzt Null ist.
Wechseln Sie in der App-Einstellung zu Ihrem Ziel und zur Info
Registerkarte. Dort löschen Sie den Wert von Main storyboard file base name
. General
Löschen Sie auf der Registerkarte den Wert für Main Interface
. Dadurch wird die Warnung entfernt.
Erstellen Sie das Fenster und den gewünschten Controller für die Erstansicht in der application:didFinishLaunchingWithOptions:
Methode des App-Delegaten :
- (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
wird aufgerufen, wenn die App in einem neuen Prozess gestartet wird. Wenn Sie zum Startbildschirm wechseln und zur App zurückkehren, wird diese Methode nicht erneut aufgerufen. (Es sei denn, iOS wird aufgrund von Speicherbeschränkungen beendet.) Stoppen Sie die App und starten Sie sie erneut über Ihre IDE. Wenn das Problem weiterhin besteht, senden Sie das Problem an SO und ich helfe Ihnen gerne weiter, Freund.
self.window = UIWindow(frame: UIScreen.mainScreen().bounds) var storyboard = UIStoryboard(name: "Main", bundle: nil) var viewController: UIViewController = // self.window!.rootViewController = viewController self.window!.makeKeyAndVisible()
Für alle Swift- Liebhaber gibt es hier die Antwort von @Travis, übersetzt in SWIFT :
Tun Sie, was @Travis vor dem Objective C-Code erklärt hat. Dann,
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
}
Dies ExampleViewController
wäre der neue anfängliche Ansichts-Controller, den Sie anzeigen möchten.
Die Schritte erklärt:
Viel Spaß beim Programmieren!
Sie können den rootViewController des Schlüsselfensters programmgesteuert festlegen (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
beispielsweise:
- (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()
-Zyklus durchläuft , ohne jedoch -s auszuführen viewDidLoad()
oder ordnungsgemäß zu initialisieren IBOutlet
. Stellen Sie sicher, dass Ihr Code dafür bereit ist.
Swift 3: Update auf den Code von @ 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
}
Sie können den Rootviewcontroller für die Navigation als Hauptansichtscontroller festlegen. Diese Idee kann für die automatische Anmeldung gemäß den Anwendungsanforderungen verwendet werden.
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];
Für StoryboardSegue-Benutzer
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];
}
Vielen Dank
Öffnen Sie das Mainstoryboard, wählen Sie zuerst die Ansicht aus, die Sie starten möchten, und öffnen Sie dann Dienstprogramme -> Attribute. Unter dem "View Controller" sehen Sie das Optionsfeld "Ist der anfängliche View Controller". Wählen Sie es einfach aus.
--- Zur überarbeiteten Frage:
Möglicherweise können Sie Folgendes versuchen: Schreiben Sie eine Methode in den Abschnitt ViewDidLoad Ihrer ersten Ansicht, und wenn die Methode beim Start der Anwendung ausgeführt wird, löst die Methode einen Übergang zu einer anderen Ansicht aus.
SWIFT 5
Wenn Sie keinen ViewController als anfänglichen ViewController im Storyboard festgelegt haben, müssen Sie zwei Dinge tun:
Schließlich können Sie jetzt Ihren Code in SceneDelegate hinzufügen:
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
Warnung behoben, die ich hatte, nachdem ich beschlossen hatte, meine anfängliche VC im Code zu instanziieren. Ein wichtiger Punkt, wenn @ rs7 "Löschen des Storyboard-Namensfelds" sagt, bedeutet dies die gesamte Zeile der Liste, nicht nur den Inhalt des Felds selbst.
Sie können sowohl initial view controller
mit dem Interface Builder als auch programmgesteuert festlegen .
Nachfolgend finden Sie einen programmgesteuerten Ansatz.
Ziel 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;
Swift:
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
Ich habe eine Routing-Klasse erstellt, um die dynamische Navigation zu handhaben und die AppDelegate-Klasse sauber zu halten. Ich hoffe, sie hilft auch anderen.
//
// 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()
}
}
Und in Ihrem AppDelegate nennen Sie dies
self.window = UIWindow(frame: UIScreen.main.bounds)
Routing.decideInitialViewController(window: self.window!)
Eine andere Lösung bei der Verwendung von Swift 3 und Swift 4 unter Vermeidung von Kraftauswurf ist diese
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
}
Und unten wird mit verwendet 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
}
In AppDelegate.swift
können Sie den folgenden Code hinzufügen:
let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "YourViewController_StorboardID")
self.window?.rootViewController = vc
self.window?.makeKeyAndVisible()
Natürlich müssen Sie Ihre Logik implementieren, basierend auf den Kriterien, für die Sie einen geeigneten Ansichts-Controller auswählen.
Vergessen Sie auch nicht, eine Identität hinzuzufügen (wählen Sie Storyboard -> Controller-Szene -> Identitätsinspektor anzeigen -> StorboardID zuweisen).
AKTUALISIERTE ANTWORT für iOS 13 und Szenendelegierter:
Stellen Sie sicher, dass Sie in Ihrer info.plist-Datei zu Anwendungsszenenmanifest -> Szenenkonfiguration -> Anwendungssitzungsrolle -> Element 0 gehen und dort auch den Verweis auf das Haupt-Storyboard löschen. Andernfalls erhalten Sie dieselbe Warnung, dass das Storyboard nicht instanziiert werden kann.
Verschieben Sie außerdem den Code vom App-Delegaten in die Szenendelegat-Methodenszene (_: willConnectTo: options :), da hier jetzt Lebenszyklusereignisse behandelt werden.
Vor ein paar Tagen bin ich auf die gleiche Situation gestoßen. Ein sehr einfacher Trick löste dieses Problem. Ich habe meinen anfänglichen Ansichts-Controller vor dem Start ausgeblendet2. Wenn der anfängliche View-Controller der richtige Controller ist, wird er in viewDidLoad auf sichtbar gesetzt. Andernfalls wird ein Übergang zum gewünschten Ansichtscontroller durchgeführt. Es funktioniert perfekt in iOS 6.1 und höher. Ich bin sicher, dass es auf früheren Versionen von iOS funktioniert.
Dank dies wurde in AppDelegate wie folgt geändert:
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()
}
Einfache Lösung gefunden - Sie müssen die "Überprüfung des anfänglichen Ansichtscontrollers" nicht aus dem Storyboard entfernen und die Registerkarte "Projektinformationen" bearbeiten und verwenden makeKeyAndVisible
, sondern nur platzieren
self.window.rootViewController = rootVC;
im
- (BOOL) application:didFinishLaunchingWithOptions:
rootVC
von instantiateViewControllerWithIdentifier
, richtig?
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
Eine andere Möglichkeit besteht darin, viewController zu präsentieren.
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = mainStoryboard.instantiateViewController(withIdentifier: "storyBoardid") as! ViewController
self.present(vc,animated:true,completion:nil)
Zuerst müssen Sie ein Objekt Ihres Storyboards erstellen und dann das Stammverzeichnis ändern (falls erforderlich). Dann verweisen Sie auf einen bestimmten Ansichts-Controller, der auf den aktuellen Ansichts-Controller verschoben wird (wenn Sie das Stammverzeichnis ändern). Andernfalls wird nur ein neuer Ansichts-Controller angezeigt, den Sie möglicherweise verwenden
Swift 4, Xcode 9
in der Datei 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 oder höher # machen den Routenansichts-Controller mit diesem einfachen Code. Wenn Sie xcode 11 oder höher verwenden, initialisieren var window: UIWindow?
Sie zuerst in 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()
Wenn Sie applicationDidFinish nicht ändern möchten, können Sie den folgenden Trick ausführen:
Legen Sie den Navigationscontroller als anfänglichen Ansichtscontroller fest und weisen Sie ihm eine benutzerdefinierte Klasse 'MyNavigationController' zu. Anschließend können Sie den Root-View-Controller während viewDidLoad optimieren. Dadurch wird der Root-View-Controller überschrieben, den Sie in Ihrem Storyboard festgelegt haben.
class MyNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
if !isLoggedIn() {
viewControllers = [R.storyboard.authentication.loginView()!]
}
}
private func isLoggedIn() -> Bool {
return false
}
}
Wählen Sie den Ansichtscontroller aus, den Sie zuerst öffnen möchten, und wechseln Sie zum Attributinspektor. Gehen Sie zur ersten Szene und überprüfen Sie, ob die Option für die anfängliche Ansichtssteuerung aktiviert ist.
Dies ist nun Ihr erster Ansichts-Controller, der beim Start der Anwendung zuerst geöffnet wird.