如何在Swift中加载初始视图控制器?

时间:2014-10-30 15:11:26

标签: ios iphone xcode swift

我正在为基于用户名 - 密码的系统开发一个应用程序。我的初始视图控制器名为LoginPageViewController。如果用户成功登录,则会加载名为MyNavigationController的导航控制器。除了LoginPageViewController之外的所有视图控制器都可以通过我在MyNavigationController的帮助下找到的旁边菜单访问:Side Menu Library

MyMenuTableViewController中描述了我的侧边菜单的查看设置,如果选择了任何表格项,则从MyMenuTableViewController加载相关的视图控制器。问题是,我还在我的侧边菜单(或菜单表,无论你打电话)中添加了“Logout”项目,如果选择了这个项目,它会向服务器发出 HTTP POST 请求注销并应加载LoginPageViewController这是我的初始视图控制器(未嵌入MyNavigationControlelr)。

问题是,虽然成功处理了注销请求,但在加载初始视图控制器(LoginPageViewController)时遇到了问题。

当我在选择退出时尝试此操作时:

self.presentViewController(destViewController, animated: true, completion: nil)

正在加载LoginPageViewController,但收到的消息如下:2014-10-30 16:59:26.038 iOpsGenie[2973:66509] Presenting view controllers on detached view controllers is discouraged <iOpsGenie.MyMenuTableViewController: 0x7f85e8fc3f10>. 如果我点击登录页面上的任何位置,我的视图就会消失,只留下一个白色的屏幕。

然后我尝试实现一个方法

 func resetAppToFirstController() {
     self.window?.rootViewController = LoginPageViewController(nibName: nil, bundle: nil)
     }
AppDelegate.swift

并在选择退出项目时调用它:

let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
appDelegate.resetAppToFirstController()

然后我在LoginPageViewController的第二行viewDidLoad函数中遇到错误,如:

fatal error: unexpectedly found nil while unwrapping an Optional value

我知道这成了一个很长的问题。我可能被视为Swift和iOS编程的新手,我试图说明问题以防止无关的响应。我真的很想知道我错过了什么。

祝你好运

4 个答案:

答案 0 :(得分:3)

我通过将resetAppToFirstController方法更改为:

来解决了这个问题
self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier(PageNames.LOGIN_PAGE) as LoginPageViewController

并在单击Logout时触发以下代码:

let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
appDelegate.resetAppToFirstController()

但是,我不知道为什么会这样。任何一点点解释都会很棒。

答案 1 :(得分:2)

  

在swift中我们可以更改根视图控制器,在这种情况下全部   其他视图控制器将被取消分配,它们将不再存在   在层次结构中。

加载初始视图控制器或更改根视图控制器或以快速方式执行注销操作

let storyboard = UIStoryboard(name: "StartingPage", bundle: NSBundle.mainBundle())      
let loginView: SignInVC = storyboard.instantiateViewControllerWithIdentifier("SignInVC") as! SignInVC
UIApplication.sharedApplication().keyWindow?.rootViewController = loginView

答案 2 :(得分:0)

请允许我建议一个更好的方法来做你想要的,好吗? 在我发布的另一个问题中,我遇到了类似的问题;请查看this question上接受的答案。

注意答案的故事板。它有一个视图控制器层次结构,允许从登录控制器启动,导航到几个控制器并从菜单执行注销。

要实现此目的,请按以下步骤操作。

  1. 使您的初始视图控制器成为导航控制器,根视图是您的登录控制器。

  2. 使您的登录控制器推送Segue菜单控制器。

  3. 从菜单视图的Logout按钮执行“unwind segue”到登录视图。

  4. 展开segue将从导航堆栈中删除所有视图,直到它到达您指定的视图。

    Unwind segue非常易于使用,可以解决很多问题!

    在登录视图控制器上添加以下方法定义:

    @IBAction func unwindToLoginScreen(segue:UIStoryboardSegue) {
    }
    

    然后,在情节提要编辑器上,选择您想要从中放松的任何视图控制器。在视图控制器的顶部,您有三个图标。

    enter image description here

    第一个代表视图控制器;第二个是第一响应者;第三个是出口门。

    从第一个图标到第三个图标执行“控制+拖动”;将出现一个下拉菜单,引用您对代码所做的所有“unwind segue”声明。我们的unwindToLoginScreen segue应该出现在这里。选择它。

    enter image description here

    在storyboard编辑器左侧栏的Document Outline上,将在视图控制器的层次结构上显示Unwind Segue。选择它并将其标识符更改为“登录”。

    现在,如果您想返回登录界面,可以调用performSegueWithIdentifier(“登录”)。

    使用展开segues的优点是你可以确定堆栈中的所有视图都被释放,你可以在origin视图控制器的prepareForSegue方法中调用准备代码,目标视图控制器中的一些代码只是在完成segue之前;并且在故事板编辑器上可以看到不同视图控制器之间的连接(不像常规段中那样明显)。

答案 3 :(得分:0)

Swift 4

在swift4中更改了语法:如果你想在StoryBoard“Main”中转到“FirstViewController” 尝试以下代码

让storyboard = UIStoryboard(名称:“Main”,bundle:Bundle.main)

让firstviewcontroller = storyboard.instantiateViewController(withIdentifier:“FirstViewController”)为! FirstViewController

UIApplication.shared.keyWindow?.rootViewController = firstviewcontroller