我想从appdelegate设置初始viewcontroller。我发现了一个非常好的答案,但它是在Objective C中,我很难在swift中实现同样的目标。
Programmatically set the initial view controller using Storyboards
- (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;
}
任何人都可以提供帮助吗?
我希望初始Viewcontroller依赖于使用条件语句满足的某些条件。
答案 0 :(得分:247)
我使用这个帖子来帮助我将目标C转换为swift,并且它的工作完美。
Instantiate and Present a viewController in Swift
Swift 2 代码:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewControllerWithIdentifier("LoginSignupVC")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
return true
}
Swift 3 代码:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "LoginSignupVC")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
return true
}
答案 1 :(得分:40)
试试这个。例如:
您应该使用UINavigationController
作为初始视图控制器。然后,您可以从故事板中将任何视图控制器设置为root。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
let storyboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController:UINavigationController = storyboard.instantiateInitialViewController() as UINavigationController
let rootViewController:UIViewController = storyboard.instantiateViewControllerWithIdentifier("VC") as UIViewController
navigationController.viewControllers = [rootViewController]
self.window?.rootViewController = navigationController
return true
}
答案 2 :(得分:21)
如果您不使用故事板,可以试试这个
var window: UIWindow?
var initialViewController :UIViewController?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
initialViewController = MainViewController(nibName:"MainViewController",bundle:nil)
let frame = UIScreen.mainScreen().bounds
window = UIWindow(frame: frame)
window!.rootViewController = initialViewController
window!.makeKeyAndVisible()
return true
}
答案 3 :(得分:21)
对于Swift 3,Swift 4:
从故事板中实例化根视图控制器:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// this line is important
self.window = UIWindow(frame: UIScreen.main.bounds)
// In project directory storyboard looks like Main.storyboard,
// you should use only part before ".storyboard" as it's name,
// so in this example name is "Main".
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
// controller identifier sets up in storyboard utilities
// panel (on the right), it called Storyboard ID
let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewControllerIdentifier") as! YourViewController
self.window?.rootViewController = viewController
self.window?.makeKeyAndVisible()
return true
}
如果您想以root身份使用UINavigationController
:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// this line is important
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewControllerIdentifier") as! YourViewController
let navigationController = UINavigationController.init(rootViewController: viewController)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
return true
}
从xib实例化根视图控制器:
几乎相同,但不是行
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewControllerIdentifier") as! YourViewController
你必须写
let viewController = YourViewController(nibName: "YourViewController", bundle: nil)
答案 4 :(得分:14)
Here is a good way to approach it. This example places a navigation controller as the root view controller, and puts the view controller of your choice within it at the bottom of the navigation stack, ready for you to push whatever you need to from it.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
// mainStoryboard
let mainStoryboard = UIStoryboard(name: "MainStoryboard", bundle: nil)
// rootViewController
let rootViewController = mainStoryboard.instantiateViewControllerWithIdentifier("MainViewController") as? UIViewController
// navigationController
let navigationController = UINavigationController(rootViewController: rootViewController!)
navigationController.navigationBarHidden = true // or not, your choice.
// self.window
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window!.rootViewController = navigationController
self.window!.makeKeyAndVisible()
}
To make this example work you would set "MainViewController" as the Storyboard ID on your main view controller, and the storyboard's file name in this case would be "MainStoryboard.storyboard". I rename my storyboards this way because Main.storyboard to me is not a proper name, particularly if you ever go to subclass it.
答案 5 :(得分:11)
我是在目标上完成的 - 希望它对你来说是有用的
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *viewController;
NSUserDefaults *loginUserDefaults = [NSUserDefaults standardUserDefaults];
NSString *check=[loginUserDefaults objectForKey:@"Checklog"];
if ([check isEqualToString:@"login"]) {
viewController = [storyboard instantiateViewControllerWithIdentifier:@"SWRevealViewController"];
} else {
viewController = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
}
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
答案 6 :(得分:6)
禁用Main.storyboard
General -> Deployment Info -> Main Interface -> remove `Main`
Info.plist -> remove Key/Value for `UISceneStoryboardFile` and `UIMainStoryboardFile`
添加情节提要ID
Main.storyboard -> Select View Controller -> Inspectors -> Identity inspector -> Storyboard ID -> e.g. customVCStoryboardId
Swift 5和Xcode 11
扩展UIWindow
class CustomWindow : UIWindow {
//...
}
由Xcode SceneDelegate.swift
生成的编辑
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: CustomWindow!
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "customVCStoryboardId")
window = CustomWindow(windowScene: windowScene)
window.rootViewController = initialViewController
window.makeKeyAndVisible()
}
//...
}
答案 7 :(得分:6)
我在Xcode 8和swift 3.0中完成了希望它对你有用,并且它的工作完美。使用以下代码:
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "ViewController")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
return true
}
如果您使用的是导航控制器,请使用以下代码:
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController:UINavigationController = storyboard.instantiateInitialViewController() as! UINavigationController
let initialViewController = storyboard.instantiateViewControllerWithIdentifier("ViewController")
navigationController.viewControllers = [initialViewController]
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
return true
}
答案 8 :(得分:6)
Swift 4:
在didFinishLaunchingWithOptions()函数中的AppDelegate.swift中添加这些行......
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Setting the Appropriate initialViewController
// Set the window to the dimensions of the device
self.window = UIWindow(frame: UIScreen.main.bounds)
// Grab a reference to whichever storyboard you have the ViewController within
let storyboard = UIStoryboard(name: "Name of Storyboard", bundle: nil)
// Grab a reference to the ViewController you want to show 1st.
let initialViewController = storyboard.instantiateViewController(withIdentifier: "Name of ViewController")
// Set that ViewController as the rootViewController
self.window?.rootViewController = initialViewController
// Sets our window up in front
self.window?.makeKeyAndVisible()
return true
}
现在,例如,当我们想要将用户驱动到登录屏幕或初始设置屏幕或返回到应用程序的主屏幕等时,我们会做很多次这样的事情。如果你想做某事就像这样,你可以把这一点作为一个岔路口。
想一想。你可以在NSUserDefaults中存储一个值,例如持有userLoggedIn布尔值和if userLoggedIn == false { use this storyboard & initialViewController... } else { use this storyboard & initialViewController... }
答案 9 :(得分:5)
上面/下面的所有答案都会产生关于故事板中没有入口点的警告。
如果你想拥有2个(或更多)依赖于某些条件的入口视图控制器(例如 conditionVariable ),你应该做的是:
使用下一个代码:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let navigationController = window!.rootViewController! as! UINavigationController
navigationController.performSegueWithIdentifier(conditionVariable ? "id1" : "id2")
return true
}
希望这有帮助。
答案 10 :(得分:5)
对于新的Xcode 11.xxx和Swift 5.xx
对于新的项目结构,AppDelegate不必对rootViewController做任何事情。
那里有一个新类来处理window(UIWindowScene)类->'SceneDelegate'文件。
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let window = self.window else {return}
// guard let _ = (scene as? UIWindowScene) else { return }
window.rootViewController = RootViewController() // Your root view controller
window.makeKeyAndVisible()
}
答案 11 :(得分:3)
这是Swift 4中的完整解决方案 在didFinishLaunchingWithOptions
中实现 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let isLogin = UserDefaults.standard.bool(forKey: "Islogin")
if isLogin{
self.NextViewController(storybordid: "OtherViewController")
}else{
self.NextViewController(storybordid: "LoginViewController")
}
}
在Appdelegate.swift中的任何位置编写此函数
func NextViewController(storybordid:String)
{
let storyBoard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let exampleVC = storyBoard.instantiateViewController(withIdentifier:storybordid )
// self.present(exampleVC, animated: true)
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = exampleVC
self.window?.makeKeyAndVisible()
}
答案 12 :(得分:3)
Swift 5和Xcode 11
因此在xCode 11中,窗口解决方案在appDelegate内部不再有效。他们将其移至SceneDelgate。您可以在SceneDelgate.swift文件中找到它。
您会注意到它现在有一个var window: UIWindow?
。
在我的情况下,我使用情节提要中的TabBarController并将其设置为rootViewController。
这是我的代码:
sceneDelegate.swift
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).
self.window = self.window ?? UIWindow()//@JA- If this scene's self.window is nil then set a new UIWindow object to it.
//@Grab the storyboard and ensure that the tab bar controller is reinstantiated with the details below.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let tabBarController = storyboard.instantiateViewController(withIdentifier: "tabBarController") as! UITabBarController
for child in tabBarController.viewControllers ?? [] {
if let top = child as? StateControllerProtocol {
print("State Controller Passed To:")
print(child.title!)
top.setState(state: stateController)
}
}
self.window!.rootViewController = tabBarController //Set the rootViewController to our modified version with the StateController instances
self.window!.makeKeyAndVisible()
print("Finished scene setting code")
guard let _ = (scene as? UIWindowScene) else { return }
}
请确保像我在此处那样将其添加到正确的场景方法中。请注意,您需要为情节提要中使用的tabBarController或viewController设置标识符名称。
在我的情况下,我这样做是为了设置stateController来跟踪选项卡视图之间的共享变量。如果您想做同样的事情,请添加以下代码...
StateController.swift
import Foundation
struct tdfvars{
var rbe:Double = 1.4
var t1half:Double = 1.5
var alphaBetaLate:Double = 3.0
var alphaBetaAcute:Double = 10.0
var totalDose:Double = 6000.00
var dosePerFraction:Double = 200.0
var numOfFractions:Double = 30
var totalTime:Double = 168
var ldrDose:Double = 8500.0
}
//@JA - Protocol that view controllers should have that defines that it should have a function to setState
protocol StateControllerProtocol {
func setState(state: StateController)
}
class StateController {
var tdfvariables:tdfvars = tdfvars()
}
注意:只需使用您自己的变量或试图跟踪的变量,我就在tdfvariables结构中列出了我的示例。
在TabController的每个视图中,添加以下成员变量。
class SettingsViewController: UIViewController {
var stateController: StateController?
.... }
然后在这些相同的文件中添加以下内容:
extension SettingsViewController: StateControllerProtocol {
func setState(state: StateController) {
self.stateController = state
}
}
它的作用是允许您避免在视图之间传递变量的单例方法。这很容易实现依赖注入模型,从长远来看,它比单例方法要好得多。
答案 13 :(得分:3)
对于 swift 4.0 。
在 didfinishedlaunchingWithOptions 方法的 AppDelegate.swift 文件中,输入以下代码。
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
let rootVC = MainViewController() // your custom viewController. You can instantiate using nib too. UIViewController(nib name, bundle)
//let rootVC = UIViewController(nibName: "MainViewController", bundle: nil) //or MainViewController()
let navController = UINavigationController(rootViewController: rootVC) // Integrate navigation controller programmatically if you want
window?.rootViewController = navController
return true
}
希望它能正常工作。
答案 14 :(得分:2)
如果您不使用情节提要。您可以通过编程方式初始化主视图控制器。
快捷键4
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let rootViewController = MainViewController()
let navigationController = UINavigationController(rootViewController: rootViewController)
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
return true
}
class MainViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
}
}
还要从部署信息中删除Main
。
答案 15 :(得分:2)
以防你想在视图控制器中而不是在应用委托中执行:只需在视图控制器中获取对AppDelegate的引用,并使用右视图控制器重置它的窗口对象因为它是rootviewController。
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let yourVC = mainStoryboard.instantiateViewControllerWithIdentifier("YOUR_VC_IDENTIFIER") as! YourViewController
appDelegate.window?.rootViewController = yourVC
appDelegate.window?.makeKeyAndVisible()
答案 16 :(得分:1)
I worked out a solution on Xcode 6.4 in swift.
// I saved the credentials on a click event to phone memory
@IBAction func gotobidderpage(sender: AnyObject) {
if (usernamestring == "bidder" && passwordstring == "day303")
{
rolltype = "1"
NSUserDefaults.standardUserDefaults().setObject(usernamestring, forKey: "username")
NSUserDefaults.standardUserDefaults().setObject(passwordstring, forKey: "password")
NSUserDefaults.standardUserDefaults().setObject(rolltype, forKey: "roll")
self.performSegueWithIdentifier("seguetobidderpage", sender: self)
}
// Retained saved credentials in app delegate.swift and performed navigation after condition check
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let usernamestring = NSUserDefaults.standardUserDefaults().stringForKey("username")
let passwordstring = NSUserDefaults.standardUserDefaults().stringForKey("password")
let rolltypestring = NSUserDefaults.standardUserDefaults().stringForKey("roll")
if (usernamestring == "bidder" && passwordstring == "day303" && rolltypestring == "1")
{
// Access the storyboard and fetch an instance of the view controller
var storyboard = UIStoryboard(name: "Main", bundle: nil)
var viewController: BidderPage = storyboard.instantiateViewControllerWithIdentifier("bidderpageID") as! BidderPage
// Then push that view controller onto the navigation stack
var rootViewController = self.window!.rootViewController as! UINavigationController
rootViewController.pushViewController(viewController, animated: true)
}
// Override point for customization after application launch.
return true
}
Hope it helps !
答案 17 :(得分:0)
用于Swift 4.2和5代码的代码:
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "dashboardVC")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
答案 18 :(得分:0)
使用来自App委托的SWRevealViewController打开一个视图控制器。
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "StoryboardName", bundle: nil)
let swrevealviewcontroller:SWRevealViewController = storyboard.instantiateInitialViewController() as! SWRevealViewController
self.window?.rootViewController = swrevealviewcontroller
self.window?.makeKeyAndVisible()
答案 19 :(得分:0)
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
}
答案 20 :(得分:0)
对于Swift 5 +
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
let submodules = (
home: HomeRouter.createModule(),
search: SearchRouter.createModule(),
exoplanets: ExoplanetsRouter.createModule()
)
let tabBarController = TabBarModuleBuilder.build(usingSubmodules: submodules)
window.rootViewController = tabBarController
self.window = window
window.makeKeyAndVisible()
}
}
答案 21 :(得分:0)
iOS 13 +
在场景代理中:
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options
connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
let vc = UIViewController() //Instead of UIViewController() we initilise our initial viewController
window?.rootViewController = vc
window?.makeKeyAndVisible()
}
答案 22 :(得分:0)
如果我的应用程序用户已经存在于钥匙串或userdefault中,则需要更改rootviewcontroller时,我认为此答案非常有用,并且非常适合我的情况。
答案 23 :(得分:0)
Swift 5.3 + 和 iOS 13.0 +
在“SceneDelegate.swift”中设置您的初始 ViewController // 仅
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
setInitialViewController()
window?.makeKeyAndVisible()
}
func setInitialViewController() {
// Set Story board Controller
/*
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "ViewController")
*/
// Set Custom Xib
let vc = FrontVC(nibName: "FrontViewController", bundle: nil)
// Navigation Controller
let nav = UINavigationController(rootViewController: vc)
nav.isNavigationBarHidden = true
window?.rootViewController = nav
}