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


77

从第一个视图控制器导航到第二个视图控制器时收到错误消息。我的编码就是这样

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,请确保选择了include xib。
gabbler 2014年

尝试添加一个完整的新视图控制器并替换LoginViewController它,看看它是否有效。
gabbler 2014年

顺便说一句,我正在使用情节提要
Mohammad Nurdin 2014年

我也是,我正在使用情节提要,并使用您的代码加载了一个xib文件,它对我有用。
gabbler 2014年

要访问代码中的情节提要,您需要在情节提要中设置其情节提要ID。
诺亚

Answers:


134

我已经找到答案了

斯威夫特4

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

迅捷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-
迈克尔·布朗

3
它隐藏了“导航栏”
Danny182 '16

15
@ Danny182如果要显示导航栏,请使用self.navigationController?.pushViewController(nextViewController, animated: true)
发烧时间:

1
如果它对UITabbarViewController有UINavigationController标记怎么办,在这种情况下如何推送UINavigationController?
基兰

它(Swift 4)以模态形式呈现新的视图控制器
subair_a

43

试试这个。这里的“ LoginViewController”是在情节提要中指定的情节提要ID。

见下文

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

我很惊讶Nurdin的答案被建议起作用(但没有成功),因为它只是调用push。当然这看起来像它应该正常工作,因为我们正在处理导航控制器
Sirens

41

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

在此处输入图片说明


1
正确答案,我投了赞成票,但为什么我们需要“ Restoration ID”?我相信“ Storyoard ID”足以应付这种情况。
Yucel Bayram,

感谢您的反馈@yucelbayram恢复标识符是您需要分配给要保留和恢复的任何视图控制器或视图的字符串。就我而言,我使用此字段是因为我需要确定功能,但是如果不需要,可以将其删除。
克里斯蒂安·莫拉

15

如果要导航到以编程方式创建的Controller,请执行以下操作:

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)

10

见我的。

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

如果使用演示样式,则可能会因预设的推导航而丢失页面的导航栏。


10

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

  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

Swift3:

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

试试看 您只是将笔尖与情节提要表达混淆了。


6

以编程方式根据不同的情况有不同的方式

  1. 加载storyenter代码hereboard笔尖文件

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

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

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

谢谢。我尝试将这种方法用于xib,相反,我需要将其用于情节提要。您的回答对我很有帮助!
乔纳斯·迪切尔曼

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

2

您可以在视图控制器的Storyboard和StoryboardId的帮助下使用代码在视图控制器之间进行导航。该代码适用于Swift 3:

let signUpVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SignUp")
self.navigationController?.pushViewController(signUpVC, animated: true)

您对答案中的代码有什么介绍或解释吗?也许第一个句子是“我认为您想要这样的代码:”。
Louis Langholtz

2

XCODE 9.2和SWIFT 3.0

ViewControllerNextViewcontroller无Segue连接

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)

1

我给你我的代码进行过渡。在此示例中,操作正在连接到UIButton。因此,请不要忘记进行设置。不要忘记在方法中设置ViewController的名称transition

不要忘记设置故事板。您需要每个viewController一个视图。将每个ViewController连接到storyBoard中的每个视图。您可以在下面的屏幕截图中看到

在此处输入图片说明 在此处输入图片说明

class PresentationViewController: UIViewController {
    override func viewDidLoad() {
         super.viewDidLoad()

         var playButton   = UIButton.buttonWithType(UIButtonType.System) as UIButton

         let image = UIImage(named: "YourPlayButton") as UIImage?

         playButton.frame = CGRectMake(0, 0, 100, 100)
         playButton.center = CGPointMake(self.view.frame.width/2, self.view.frame.height/2)
         playButton.addTarget(self, action: "transition:", forControlEvents:  UIControlEvents.TouchUpInside)
         playButton.setBackgroundImage(image, forState: UIControlState.Normal)

         self.view.addSubview(playButton)
    }


func transition(sender:UIButton!)
{
    println("transition")
    let secondViewController = self.storyboard?.instantiateViewControllerWithIdentifier("YourSecondViewController") as UIViewController

    let window = UIApplication.sharedApplication().windows[0] as UIWindow
    UIView.transitionFromView(
        window.rootViewController!.view,
        toView: secondViewController.view,
        duration: 0.65,
        options: .TransitionCrossDissolve,
        completion: {
            finished in window.rootViewController = secondViewController
    })
}
}

1

如果要构建不带拖放功能的UI(不使用情节提要),并且要导航默认页面或ViewController.swift到另一个页面?请按照以下步骤操作:1)添加一个类(.swift)2)导入UIKit 3)声明类名,例如

class DemoNavigationClass :UIViewController{
     override func viewDidLoad(){
         let lbl_Hello = UILabel(frame: CGRect(x:self.view.frame.width/3, y:self.view.frame.height/2, 200, 30));
lbl_Hello.text = "You are on Next Page"
lbl_Hello.textColor = UIColor.white
self.view.addSubview(lbl_Hello)
    }
}

在创建第二页之后,返回到第一页(ViewController.swift)。在这里在viewDidLoad方法中创建一个按钮

let button = UIButton()
button.frame = (frame: CGRect(x: self.view.frame.width/3, y: self.view.frame.height/1.5,   width: 200, height: 50))
 button.backgroundColor = UIColor.red
 button.setTitle("Go to Next ", for: .normal)
 button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
 self.view.addSubview(button)

现在在同一类的viewDidLoad()外部定义buttonAction方法

func buttonAction(sender: UIButton!) 
{
    let obj : DemoNavigationClass = DemoNavigationClass();
    self.navigationController?.pushViewController(obj, animated: true)
}

在main.storyboard中保留我忘记的一件事,其中有一个带有箭头的场景,选择该箭头并按Delete键

现在,拖放navigationation控制器随附的navigationcontroller并删除tableview。选择navigationcontroller按键盘上的控件,然后将其拖到故事板上的另一个场景,即ViewController。这意味着您的viewcontroller成为root viewcontroller,希望对您有所帮助。感谢main.storyboard,拖放Navigationcontroller,


1
let signUpVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SignUp")
// self.present(signUpVC, animated: false, completion: nil)
self.navigationController?.pushViewController(signUpVC, animated: true)

3
您需要在答案周围添加一些内容,并对其进行一些说明。
麻雀

1

除了上面将导航视图控制器设置在应用程序屏幕上方的良好答案之外,您还可以将其添加到块内的AppDelegate.swift文件中,如下所示

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

    window = UIWindow()
    window?.makeKeyAndVisible()
    window?.rootViewController = UINavigationController(rootViewController: LoginViewController())

    return true

}

1

斯威夫特4.0.3

 @IBAction func registerNewUserButtonTapped(_ sender: Any) {

        print("---------------------------registerNewUserButtonTapped --------------------------- ");

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

        let nextViewController = storyBoard.instantiateViewController(withIdentifier: "RegisterNewUserViewController") as! RegisterNewUserViewController
        self.present(nextViewController, animated:true, completion:nil)

    }

更改我们的控制器名称RegisterNewUserViewController


应该是storyboard
Lucas

1

我认为您正在寻找这样的东西:

let signUpViewController = SignUpViewController()
present(signUpViewController, animated: true, completion: nil)

如果要全屏显示新页面:

present(signUpViewController, animated: true, completion: nil)

希望这可以帮助 :)


0

我不确定尝试以下步骤,我认为以下原因可能会导致错误。

  • 您在XCode外部重命名了一些文件。要解决该问题,请从您的项目中删除文件,然后重新导入项目中的文件。
  • 在“构建阶段”->“复制捆绑包资源”中检查并添加丢失的Nib文件。最后检查“ nib”名称的拼写,正确无误,区分大小写。
  • 文件检查器中检查.xib / storyboard文件的属性,选择框上的“ Target Membership ”属性,然后将xib / storyboard文件与目标链接。
  • 例如不正确的NIB类型。右键单击文件,然后单击“获取信息”以确认类型是否符合您的期望。

0
 let vc = DetailUserViewController()
 vc.userdetails = userViewModels[indexPath.row]
 self.navigationController?.pushViewController(vc, animated: true)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.