[英]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.