以编程方式设置初始视图控制器 Swift

Posted

技术标签:

【中文标题】以编程方式设置初始视图控制器 Swift【英文标题】:Setting Initial View Controller Programmatically Swift 【发布时间】:2016-03-19 19:22:36 【问题描述】:

我在这里看到了关于堆栈溢出的冗长的 Objective-C 答案,但没有快速的答案。

如何从视图控制器以编程方式快速更改初始视图控制器?

我认为它会是这样的:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
storyboard.setInitialViewController(identifier: ViewController())

但是不,这没有任何作用。第一行很好,第二行的功能就是不存在。

【问题讨论】:

set initial viewcontroller in appdelegate - swift的可能重复 不是重复的,因为原始问题询问它是如何在应用程序委托中完成的,但这询问如何从视图控制器设置初始视图控制器。 您能否更准确地解释一下您需要从另一个视图控制器设置初始视图控制器以更好地帮助您。 我添加了一个答案来澄清你。 【参考方案1】:

要在视图控制器中而不是在应用程序委托中执行此操作:只需在视图控制器中获取对 AppDelegate 的引用,然后使用正确的视图控制器重置它的窗口对象,因为它是 rootviewController。

第 1 步:制作一些用户可以调整的 NSUserDefaults。几个按钮,表格视图中的一些开关,等等。然后当用户点击按钮时,我们更改 NSUserDefault。

@IBAction func SwitchLaunchViewtoViewController2(sender: AnyObject) 
  defaults.setObject("ViewController2", forKey: "LaunchView")

@IBAction func SwitchLaunchViewtoViewController1(sender: AnyObject) 
  defaults.setObject("ViewController1", forKey: "LaunchView")

将设置视图控制器中的几个按钮与这些功能挂钩,我们就开始了。

第 2 步:为您希望能够设置为启动视图的所有情节提要设置情节提要 ID。因此,对于每个可能是初始视图控制器的视图控制器:

-进入你的故事板。

-点击视图控制器。

-在右侧边栏中,点击类似报纸的图标,您可以在其中控制班级。

-在“身份”部分(第三行)中,选中“使用故事板 ID”(确保已打开),然后在“故事板 ID”文本字段中输入类似“VC1”的内容。确保为每个视图控制器选择不同的 Storyboard ID。

-对每个视图控制器重复。

第 3 步:在 AppDelegate.swift 文件中设置您的初始视图控制器。进入您的应用程序委托的func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 部分。

添加这个以从您之前创建的 NSUserDefault 中读取:

let defaults = NSUserDefaults.standardUserDefaults()
    if let launchview = defaults.stringForKey("LaunchView")
    


这会查找名为“LaunchView”(您在步骤 1 中创建)的 NSUserDefault 字符串,并在找到匹配的 NSUserDefault 时将其设置为新变量 launchview。

然后,在if let launchview... 括号内,我们要检查您将LaunchView 设置为什么。对于您在步骤 1 中设置为 LaunchView 的每个对象(在示例中,我做了 "ViewController2""ViewController1"),您必须在此处检查它。因此,在这些括号内,我们添加以下内容:

if launchview == "ViewController2" 

 else if launchview == "ViewController1" 


然后,在每个 if 语句中,我们添加以下代码:

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) // this assumes your storyboard is titled "Main.storyboard"
let yourVC = mainStoryboard.instantiateViewControllerWithIdentifier("YOUR_VC_IDENTIFIER") as! YourViewController // inside "YOUR_VC_IDENTIFIER" substitute the Storyboard ID you created in step 2 for the view controller you want to open here. And substitute YourViewController with the name of your view controller, like, for example, ViewController2.
appDelegate.window?.rootViewController = yourVC
appDelegate.window?.makeKeyAndVisible()

当您的应用程序在后台运行一段时间后完成加载时,这将打开所选窗口。

您完成的 AppDelegate 的 didFinishLoadingWithOptions 部分可能如下所示: (不要只是复制粘贴,阅读上面的说明)

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 

let defaults = NSUserDefaults.standardUserDefaults()
        if let launchview = defaults.stringForKey("LaunchView")
        

            if launchview == "ViewController1" 

        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("VC1") as! ViewController1
        appDelegate.window?.rootViewController = yourVC
        appDelegate.window?.makeKeyAndVisible()

             else if launchview == "ViewController2" 
                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("VC1") as! ViewController1
                appDelegate.window?.rootViewController = yourVC
                appDelegate.window?.makeKeyAndVisible()
            

        

        return true
   

我希望这对您有所帮助,非常感谢 Ankit Goel 在这方面为我提供了这么多帮助。阅读下面的 cmets 了解更多信息。

最后一点:如果您在设置视图中使用开关,请确保在您从 NSUserDefault LaunchView 读取用户最后选择的设置视图控制器的 viewDidLoad 上。

【讨论】:

谢谢;我应该将所有这些代码放在我的 App Delegate 中的哪里(在哪个部分?)以及如何“在我的视图控制器中获取对 App Delegate 的引用并重置其窗口对象”? 在视图控制器中添加此代码,例如你可以把它放在 viewDidLoad() 或 viewDidAppear() 或任何其他方法中.. @AnkitGoel 恐怕您的方式根本不准确,假设您已经使用一些初始视图控制器进入应用程序,您何时准确放置代码?您在通过后设置初始视图控制器,这是错误的。这是因为此代码用于application:didFinishLaunchingWithOptions: @VictorSigler 问题指定他想从视图控制器执行此操作!!!并将这段代码放在 viewDidLoad() 中,我已经测试过代码并且它可以工作。当您需要更改整个视图控制器层次结构时,这特别有用.. @JohnRamos 打开故事板,单击视图控制器,在右侧窗格中单击第三个图标,在其中为视图控制器设置自定义类,在该图标下方,您将看到身份检查器可以为 viewcontroller 设置你的 storyboardid【参考方案2】:

为 Swift 3 更新

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 

    window = UIWindow(frame: UIScreen.main.bounds)
    window?.makeKeyAndVisible()

    window?.rootViewController = UINavigationController(rootViewController: ViewController())

    return true

【讨论】:

【参考方案3】:

首先,可以使用问题中公开的代码在application:didFinishLaunchingWithOptions: 中以编程方式设置应用程序的初始视图控制器:

set initial viewcontroller in appdelegate - swift

您可以管理您想要在其中显示的所有条件以在条件基础中显示一个或另一个UIViewController

例如,假设您希望在您的应用程序中仅在第一次安装应用程序时显示演练,然后再显示另一个登录屏幕,然后再显示另一个,但您只在第一次安装时显示演练和登录以防万一之前和另一个没有被记录。

这当然可以通过多种方式来处理,我只尝试向您解释其中一种方法。

为此,您可以设置一个名为 SplashViewController 的控制器,例如,它是您的初始 UIViewController,在其中您显示应用程序的图像(大图像徽标、启动屏幕)和您的进程你去一个地方或另一个地方。通过这种方式,您可以清理大量 AppDelegate 中的代码,并且更容易对其进行单元测试。

现在,如果您想从另一个 UIViewController 内部转到另一个 UIViewController,您可以使用以下代码:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewControllerWithIdentifier("ControllerName") as! ControllerName
self.presentViewController(viewController, animated: true, completion: nil)

希望对你有所帮助。

【讨论】:

您假设代码需要在应用程序启动时运行(当问题中提到这需要从视图控制器完成时)。如果用户已经启动了应用程序并且他需要重置窗口的根视图,那么您需要触发本地通知并在应用程序委托中观察它,或者您可以简单地按照下面给出的解决方案。 @VictorSigler 非常感谢您的所有帮助,您确实帮助我找到了解决问题的方法(所以我会给您一个大拇指!)。 @VictorSigler 另外,如果您对 Ankit Goel 的回答表示反对,那么如果您可以删除反对票,那就太好了,因为他也确实帮助了我!你们俩都非常有帮助。 @JohnRamos 当然,现在提供的答案值得一票:)

以上是关于以编程方式设置初始视图控制器 Swift的主要内容,如果未能解决你的问题,请参考以下文章

swift 以编程方式设置初始控制器

在 Swift 中以编程方式设置根视图控制器

为啥我们不能在以编程方式设置初始视图控制器时以编程方式在视图控制器之间跳转?

目标 c:iOS 13+ 以编程方式设置初始根视图控制器

以编程方式设置 rootViewController 不起作用,仅在 Xcode 11 中从情节提要中选择初始视图控制器

Swift 从按钮内部、弹出框和单元格以编程方式在地图顶部打开一个新的视图控制器