【问题标题】:Unable to switch back to the previous rootViewController programatically无法以编程方式切换回之前的根视图控制器
【发布时间】:2015-01-20 22:40:49
【问题描述】:

我在故事板上有两个视图控制器,我想在某些情况下(例如,按下按钮)在它们之间切换,所以我编写了以下代码:

// FirstViewController.swift
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let rootViewController = storyboard.instantiateViewControllerWithIdentifier("SecondViewController") as SecondViewController
if let keyWindow = UIApplication.sharedApplication().keyWindow {
    keyWindow.rootViewController = rootViewController
}

// SecondViewController.swift
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let rootViewController = storyboard.instantiateViewControllerWithIdentifier("FirstViewController") as FirstViewController
if let keyWindow = UIApplication.sharedApplication().keyWindow {
    keyWindow.rootViewController = rootViewController
}

从第一个视图控制器切换到第二个按预期工作,但是当我尝试切换回第一个视图控制器时,它会改变一会儿,但会再次自动显示第二个视图控制器。奇怪的是,如果我将“切换”代码更改为以下

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

它按预期工作。

为什么?我究竟做错了什么?我该如何解决?

提前致谢。

【问题讨论】:

  • 为什么你只是改变根视图控制器而不是进行模态演示或推送?当你回到第一个控制器时,你想回到你来自的同一个实例(因为你的代码没有这样做,它正在创建一个新实例)?
  • @rdelmar 因为我认为这是以编程方式更改视图控制器的更合适的方式
  • 没有理由使用此代码转到第一个控制器应该自动转到第二个控制器,除非您要在第一个控制器的 viewDidAppear 中转到第二个控制器。
  • 第一次分配UIWindow 的rootViewController 属性后,您不应触摸它。相反,你必须想出一些其他的方式来呈现它。就像视图控制器演示或一些容器 UIViewController 管理它的孩子。
  • @mstysf,为什么你认为你不应该触摸根视图控制器?我在 Apple 的文档中没有看到任何内容说你不应该这样做。事实上,在 UIWindow 类的顶部,它说:“要更改应用程序显示的内容,您可以更改窗口的根视图;” rootViewController 属性的描述中也没有说明不要更改它。

标签: ios xcode swift xcode6 uistoryboard


【解决方案1】:

您可以通过创建基本导航控制器并将其用作切换器来做类似的事情,而不是更改窗口的 rootViewController:

class BaseViewController: UINavigationController {

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder);

        // You can skip this step if you instantiate BaseViewController in a
        // storyboard and set its root segue to FirstViewController
        self.viewControllers = [FirstViewController(nibName:"FirstViewController", bundle:nil)]
    }

    override func pushViewController(viewController: UIViewController, animated: Bool) {
        self.viewControllers = [viewController]
    }
}


class FirstViewController: UIViewController {

    required init(coder aDecoder: NSCoder) {
        super.init(nibName: "FirstViewController", bundle: nil)
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    @IBAction func goToSecond(sender: AnyObject) {
        self.navigationController?.pushViewController(SecondViewController(nibName:"SecondViewController", bundle:nil), animated: true);   
    }
}


class SecondViewController: UIViewController {

    required init(coder aDecoder: NSCoder) {
        super.init(nibName: "SecondViewController", bundle: nil)        
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    @IBAction func goToFirst(sender: AnyObject) {
        self.navigationController?.pushViewController(FirstViewController(nibName:"FirstViewController", bundle:nil), animated: true);    
    }
}

在这里,我正在从 nib 加载视图控制器。但是,您可以像在示例中那样轻松地从情节提要中实例化它们。此外,您可以隐藏导航栏,使其看起来不像导航上下文。

【讨论】:

    猜你喜欢
    • 2017-11-30
    • 2010-10-29
    • 2011-05-09
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    相关资源
    最近更新 更多