如何使用Swift从一个视图控制器导航到另一个视图控制器

93

我想从一个视图控制器导航到另一个视图控制器。如何将以下 Objective-C 代码转换为 Swift?

UIViewController *viewController = [[self storyboard] instantiateViewControllerWithIdentifier:@"Identifier"];
UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:viewController];
[self.navigationController pushViewController:navi animated:YES];

请查看:https://dev59.com/nV4c5IYBdhLWcg3w7t_E#38244058 - Jayprakash Dubey
16个回答

230

创建一个Swift文件 (SecondViewController.swift) 用于第二个视图控制器,在适当的函数中输入以下内容:

let secondViewController = self.storyboard.instantiateViewControllerWithIdentifier("SecondViewController") as SecondViewController
self.navigationController.pushViewController(secondViewController, animated: true)


Swift 2+

let mapViewControllerObj = self.storyboard?.instantiateViewControllerWithIdentifier("MapViewControllerIdentifier") as? MapViewController
self.navigationController?.pushViewController(mapViewControllerObj!, animated: true)

Swift 4

let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "IKDetailVC") as? IKDetailVC
self.navigationController?.pushViewController(vc!, animated: true)

1
@audrey,你好,如何设置navigationController? - Sanjivani
1
@Sanjivani,你的视图控制器可以使用Storyboard创建,并将你的firstViewController分配为rootViewController。你的导航控制器(Swift)类将如下所示: import UIKit`class SwiftNavigationController: UINavigationController { init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) // 自定义初始化 }override func viewDidLoad() { super.viewDidLoad() }}` - Audrey Sobgou Zebaze
3
我也遇到了同样的问题,我卡在了如何从一个 ViewController 跳转到另一个 ViewController 上。当我尝试运行你的代码时,在第二行代码处出现了错误:unexpectedly found nil while unwrapping an Optional value。请帮忙解决一下。 - Raghavendra
1
我在使用animated参数时遇到了问题,错误信息如下: "无法将表达式的类型'$T7??'转换为类型'BooleanLiteralConvertible'"。 - Morkrom
2
你需要确保你的控制器嵌入到 NavigationController 中才能使其正常工作,否则会出现错误。 - kakubei
显示剩余5条评论

35

根据我的经验,navigationController 值为 nil,所以我将我的代码改为:

let next = self.storyboard?.instantiateViewControllerWithIdentifier("DashboardController") as! DashboardController
self.presentViewController(next, animated: true, completion: nil)

别忘了在StoryBoardidentity inspector中设置视图控制器的StoryBoard Id


3
这是因为您的视图控制器没有嵌入导航视图控制器。 - Francis Reynolds

18
如果您不希望出现返回按钮(这也是我的情况,因为我想在用户登录后展示),则可以通过以下方法设置导航控制器的根目录:
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("YourViewController") as! YourViewController
        let navigationController = UINavigationController(rootViewController: vc)
        self.presentViewController(navigationController, animated: true, completion: nil)

16

SWIFT 3.01

let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "Conversation_VC") as! Conversation_VC
self.navigationController?.pushViewController(secondViewController, animated: true)

8

在 Swift 4.0 中

var viewController: UIViewController? = storyboard().instantiateViewController(withIdentifier: "Identifier")
var navi = UINavigationController(rootViewController: viewController!)
navigationController?.pushViewController(navi, animated: true)

6
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let home = storyBoard.instantiateViewController(withIdentifier: "HOMEVC") as! HOMEVC
navigationController?.pushViewController(home, animated: true);

我认为这不是Swift或Objc语法。 - SPatel

5
在Swift 4.1和Xcode 10中,这里的AddFileViewController是第二个视图控制器。故事板ID为AFVC。
let next = self.storyboard?.instantiateViewController(withIdentifier: "AFVC") as! AddFileViewController
self.present(next, animated: true, completion: nil)

//OR

//If your VC is DashboardViewController
let dashboard = self.storyboard?.instantiateViewController(withIdentifier: "DBVC") as! DashboardViewController
self.navigationController?.pushViewController(dashboard, animated: true)

如果需要,使用线程(thread)

例如:

DispatchQueue.main.async { 
    let next = self.storyboard?.instantiateViewController(withIdentifier: "AFVC") as! AddFileViewController
    self.present(next, animated: true, completion: nil) 
}

如果你想在一段时间后移动。
例如:
//To call or execute function after some time(After 5 sec)
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
    let next = self.storyboard?.instantiateViewController(withIdentifier: "AFVC") as! AddFileViewController
    self.present(next, animated: true, completion: nil) 
} 

3
在Swift 3中,
let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "NextViewController") as! NextViewController        
self.navigationController?.pushViewController(nextVC, animated: true)

3

Swift 3

let secondviewController:UIViewController =  self.storyboard?.instantiateViewController(withIdentifier: "StoryboardIdOfsecondviewController") as? SecondViewController

self.navigationController?.pushViewController(secondviewController, animated: true)

2

Swift 5.0 最佳实践

更加可重用和易读

创建一个协议

protocol Storyboarded { }

现在创建协议的扩展。
extension Storyboarded where Self: UIViewController {
    
    static func instantiateFromMain() -> Self {
        let storyboardIdentifier = String(describing: self)
        // `Main` can be your stroyboard name.
        let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
        
        guard let vc = storyboard.instantiateViewController(withIdentifier: storyboardIdentifier) as? Self else {
            fatalError("No storyboard with this identifier ")
        }
        return vc
    }
}
// Make a ViewController extension to use on all of your ViewControllers
extension UIViewController: Storyboarded {}

如何使用
  let vc = MyViewController.instantiateFromMain()
  //here you can pass any data to the next view controller. for example we have a variable with name `myString` in our next view contoller and we want to pass the data my `self viewController`
  vc.myString = "This string passed by MyViewController"
  self.navigationController?.pushViewController(vc, animated: true)

注意:你需要在Storyboard上使用与UIViewController类相同的标识符。请查看下面的示例。

enter image description here


如果它是Storyboarded的扩展,如何调用它 - Pramod Shukla
@Pramod Shukla 确认你的 ViewController 上使用了 Storyboarded 协议,然后你就可以使用它了。或者创建一个视图控制器扩展,类似于这样 extension UIViewController: Storyboarded {} - Rashid Latif
@pramod-shukla 我也更新了我的答案,你可以相应地使用它。 - Rashid Latif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接