[英]set initial viewcontroller in appdelegate - swift
我想從 appdelegate 設置初始視圖控制器。 我找到了一個非常好的答案,但是它在目標 C 中,我無法快速實現相同的目標。
- (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 依賴於使用條件語句滿足的某些條件。
我使用這個線程來幫助我將目標 C 轉換為 swift,並且它工作得很好。
在 Swift 中實例化並呈現一個 viewController
斯威夫特 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
}
斯威夫特 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
}
嘗試這個。 例如:您應該使用UINavigationController
作為初始視圖控制器。 然后,您可以將任何視圖控制器設置為故事板中的根。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController = storyboard.instantiateInitialViewController() as UINavigationController
let rootViewController = storyboard.instantiateViewControllerWithIdentifier("VC") as UIViewController
navigationController.viewControllers = [rootViewController]
self.window?.rootViewController = navigationController
return true
}
查看我的故事板屏幕。
對於新的 Xcode 11.xxx 和 Swift 5.xx,目標設置為 iOS 13+。
對於新的項目結構,AppDelegate 不需要對 rootViewController 做任何事情。
有一個新類來處理 window(UIWindowScene) 類 -> 'SceneDelegate' 文件。
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
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)
window.rootViewController = // Your RootViewController in here
self.window = window
window.makeKeyAndVisible()
}
}
斯威夫特 3、斯威夫特 4:
將第一行更改為
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
其余的都是一樣的。
斯威夫特 5+:
從故事板實例化根視圖控制器:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: 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 its 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 is called 'Storyboard ID'
let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewControllerIdentifier") as! YourViewController
self.window?.rootViewController = viewController
self.window?.makeKeyAndVisible()
return true
}
如果你想使用UINavigationController
作為 root:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: 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)
如果你不使用故事板,你可以試試這個
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
}
Swift 4.2 和 5 代碼的代碼:
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: "dashboardVC")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
}
對於Xcode 11+
and for Swift 5+
:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
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)
window.rootViewController = // Your RootViewController in here
self.window = window
window.makeKeyAndVisible()
}
}
}
這是接近它的好方法。 這個例子將一個導航控制器作為根視圖控制器,並將您選擇的視圖控制器放在導航堆棧的底部,准備好從它推送您需要的任何內容。
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()
}
為了使這個示例工作,您需要將“MainViewController”設置為主視圖控制器上的故事板 ID,在這種情況下,故事板的文件名將是“MainStoryboard.storyboard”。 我以這種方式重命名我的故事板,因為 Main.storyboard 對我來說不是一個合適的名字,特別是如果你去繼承它。
我已經在 Objective-C 中完成了。 我希望它對你有用。
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];
在 AppDelegate 中初始化 ViewController
禁用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")
//or if your storyboard has `Is Initial View Controller`
let storyboard = UIStoryboard(name: String(describing: SomeViewController.self), bundle: nil)
let initialViewController = storyboard.instantiateInitialViewController()
window = CustomWindow(windowScene: windowScene)
window.rootViewController = initialViewController
window.makeKeyAndVisible()
}
//...
}
如果您不使用故事板。 您可以以編程方式初始化主視圖控制器。
斯威夫特 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
}
}
並從Deployment Info 中刪除Main
。
我已經在 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
}
斯威夫特 4:
在 AppDelegate.swift 中的 didFinishLaunchingWithOptions() 函數中添加這些行...
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... }
好吧,上面/下面的所有答案都產生了關於故事板中沒有入口點的警告。
如果您想擁有 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 }
希望這可以幫助。
這是 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()
}
以防萬一您想在視圖控制器中而不是在應用程序委托中執行此操作:只需在視圖控制器中獲取對 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()
對於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
}
希望它能正常工作。
斯威夫特 5 和 Xcode 11
因此,在 xCode 11 中,窗口解決方案在 appDelegate 中不再有效。 他們將其移至 SceneDelgate。 您可以在 SceneDelgate.swift 文件中找到它。
你會注意到它現在有一個var window: UIWindow?
展示。
在我的情況下,我使用故事板中的 TabBarController 並希望將其設置為 rootViewController。
這是我的代碼:
場景委托.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 來跟蹤選項卡視圖之間的共享變量。 如果您希望做同樣的事情,請添加以下代碼...
狀態控制器.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
}
}
這樣做的目的是讓您避免在視圖之間傳遞變量的單例方法。 這很容易讓依賴注入模型在長期運行時比單例方法好得多。
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()
}
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 !
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
}
使用 SWRevealViewController 從 App 委托打開一個視圖控制器。
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()
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()
}
}
如果我的應用程序用戶已經存在於鑰匙串或 userdefault 中,我發現這個答案很有幫助並且非常適合我的情況,當我需要更改 rootviewcontroller 時。
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
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.