以编程方式导航到另一个视图控制器/场景。

93

我在从第一个视图控制器导航到第二个视图控制器时遇到了错误消息。我的代码像这样

let vc = LoginViewController(nibName: "LoginViewController", bundle: nil)
self.navigationController?.pushViewController(vc, animated: true)

问题是我总是收到这种错误信息

2014-12-09 16:51:08.219 XXXXX[1351:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </var/mobile/Applications/FDC7AA0A-4F61-47E7-955B-EE559ECC06A2/XXXXX.app> (loaded)' with name 'LoginViewController''
*** First throw call stack:
(0x2efcaf0b 0x39761ce7 0x2efcae4d 0x31b693f9 0x31ac1eaf 0x3191e365 0x317fe895 0x318a930d 0x318a9223 0x318a8801 0x318a8529 0x318a8299 0x318a8231 0x317fa305 0x3147631b 0x31471b3f 0x314719d1 0x314713e5 0x314711f7 0x3146af1d 0x2ef96039 0x2ef939c7 0x2ef93d13 0x2eefe769 0x2eefe54b 0x33e6b6d3 0x3185d891 0x4ccc8 0x4cd04 0x39c5fab7)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

您需要在项目中添加一个 LoginViewController.xib 文件。当您创建 LoginViewController.swift 时,请确保选择了包括 xib。 - gabbler
尝试添加一个完整的新视图控制器并替换“LoginViewController”,看看是否有效。 - gabbler
顺便说一下,我正在使用故事板。 - Nurdin
我也是,我正在使用Storyboard,并且使用了你的代码来加载一个xib文件,对我来说它起作用了。 - gabbler
要在代码中访问故事板,您需要在故事板中设置其故事板ID。 - Noah
20个回答

149

我已经找到答案

Swift 4

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "nextView") as! NextViewController
self.present(nextViewController, animated:true, completion:nil)

Swift 3

->

Swift 3

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)

let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("nextView") as NextViewController
self.presentViewController(nextViewController, animated:true, completion:nil)

6
在 ViewController 中,您可以使用 self.StoryBoard 访问故事板。 - Michael Brown
3
它隐藏了“导航栏”。 - DanielZanchi
18
如果您希望显示导航栏,请使用self.navigationController?.pushViewController(nextViewController, animated: true) - Fever
1
如果它有UINavigationController标签到UITabbarViewController,那么在这种情况下如何推动UINavigationController? - kiran
它(Swift 4)以模态方式呈现新的视图控制器。 - subair_a

50

试试这个。这里的“LoginViewController”是在故事板中指定的storyboardID。

请参见下文:

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

我很惊讶Nurdin的答案被建议可以工作(但实际上并没有),因为它只是调用了push。当然,这看起来应该可以工作,因为我们正在处理导航控制器。 - Allison

44

XCODE 8.2 和 SWIFT 3.0

展示一个已存在的 UIViewController

let loginVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
self.present(loginVC, animated: true, completion: nil)

推送一个已存在的 UIViewController

let loginVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
self.navigationController?.pushViewController(loginVC, animated: true)

请记得您可以按照以下步骤设置UIViewController的标识符:

  • 选择Main.storyboard
  • 选择您的UIViewController
  • 在右侧搜索“工具”
  • 选择身份验证检查器
  • 在身份验证部分中搜索“Storyboard ID”
  • 为您的UIViewController设置标识符

enter image description here


1
真实的回答,我投了赞成票,但我们为什么需要“恢复标识”?我相信“故事板标识”对于这种情况已足够。 - Yucel Bayram
感谢您的反馈@yucelbayram。恢复标识符是一个字符串,您需要为希望保留和恢复的任何视图控制器或视图分配该字符串。在我的情况下,我使用此字段是因为我需要确定功能,但如果您不需要它,可以将其删除。 - Cristian Mora

17
如果您想要导航到以编程方式创建的控制器,则请执行以下操作:
let newViewController = NewViewController()
self.navigationController?.pushViewController(newViewController, animated: true)

如果你想要导航到标识符为"newViewController"的StoryBoard上的Controller,则需要执行以下步骤:

let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "newViewController") as! NewViewController
        self.present(newViewController, animated: true, completion: nil)

14

Swift3:

=>

Swift3:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController("LoginViewController") as UIViewController
self.navigationController?.pushViewController(vc, animated: true)

试一下这个。你刚才混淆了 nib 和 storyboard 表示。


11

您可以使用以下代码以编程方式从一个场景移动到另一个场景:

  let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)

  let objSomeViewController = storyBoard.instantiateViewControllerWithIdentifier(“storyboardID”) as! SomeViewController

  // If you want to push to new ViewController then use this
  self.navigationController?.pushViewController(objSomeViewController, animated: true)

  // ---- OR ----

  // If you want to present the new ViewController then use this
  self.presentViewController(objSomeViewController, animated:true, completion:nil) 

storyBoardID是您在Interface Builder中设置场景的值。如下所示:

如何设置storyboardID的屏幕截图


10

看我的。

func actioncall () {
    let loginPageView = self.storyboard?.instantiateViewControllerWithIdentifier("LoginPageID") as! ViewController
    self.navigationController?.pushViewController(loginPageView, animated: true)
}

如果您使用演示风格,可能会因为预设的pushnavigation而失去页面的导航栏。


8

根据不同情况,有不同的编程方法。

  1. load storyenter code hereboard nib file

    let yourVc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "YourViewController") as! YourViewController;
    self.present(yourVc, animated: true, completion: nil)
    
  2. Load from xib

    let yourVc = YourViewController.init(nibName: "YourViewController", bundle: nil)
    self.present(yourVc, animated: true, completion: nil)
    
  3. Navigate through Segue

    self.performSegue(withIdentifier: "your UIView", sender: self)
    

谢谢。我尝试使用XIB的方法,但实际上我需要的是Storyboard的方法。你的回答帮了我很多! - Jonas Deichelmann

3
let VC1 = self.storyboard!.instantiateViewController(withIdentifier: "MyCustomViewController") as! ViewController
let navController = UINavigationController(rootViewController: VC1)
self.present(navController, animated:true, completion: nil)

3
Xcode 9.2和Swift 3.0
ViewController转换为NextViewcontroller,而不需要连线连接。
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "NextViewController") as! NextViewController
self.navigationController?.pushViewController(nextViewController, animated:true)

或者

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

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