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

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个回答

2
除了上面的好答案之外,在您的应用程序屏幕顶部设置导航视图控制器,您可以将其添加到您的AppDelegate.swift文件中块内,如下所示。
 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

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

    return true

}

2

您可以通过故事板和视图控制器的storyboardId,在代码中实现视图控制器之间的导航。以下代码适用于Swift 3:

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

你能否为你的答案中的代码提供一些介绍或解释?也许可以用像这样的第一句话:“我认为你想要这样的代码:”。 - Louis Langholtz

2
 let vc = DetailUserViewController()
 vc.userdetails = userViewModels[indexPath.row]
 self.navigationController?.pushViewController(vc, animated: true)

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
你需要在你的回答周围添加一些内容,并稍微解释一下。 - Sparrow

1
我不确定,请尝试以下步骤,我认为可能是以下原因导致错误:
- 您在XCode之外重命名了一些文件。要解决此问题,请从项目中删除这些文件,并重新将这些文件导入项目。 - 在“Build phases->Copy bundle resources”中检查并添加缺失的Nib文件。最后检查Nib名称的拼写是否正确,大小写敏感。 - 在“文件检查器”中检查.xib/storyboard文件的属性,属性“目标成员资格”位于选择框上,然后您的xib/storyboard文件与目标链接。 - 例如,NIB类型不正确。右键单击文件,然后单击“获取信息”以验证类型是否符合预期。

1
我把我的代码给你,以便进行过渡。在这个例子中,操作是连接到一个UIButton。所以不要忘记设置它。 不要忘记在transition方法中设置您的ViewController的名称。 同时也不要忘记设置您的storyboard。您需要为每个viewController拥有一个视图。将每个ViewController连接到storyBoard中的每个视图。您可以在下面的屏幕截图中看到。

enter image description here enter image description here

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)

现在在同一个类中,将buttonAction方法定义在viewDidLoad()之外。
func buttonAction(sender: UIButton!) 
{
    let obj : DemoNavigationClass = DemoNavigationClass();
    self.navigationController?.pushViewController(obj, animated: true)
}

我忘记了一件事,即在main.storyboard中有一个带箭头的场景,选择该箭头并按下删除按钮。

现在拖放一个navigationcontroller并删除随navigationcontroller一起出现的tableview。 选择navigationcontroller,在键盘上按住control键并将其拖到Storyboard上的另一个场景中,即ViewController。 这意味着您的视图控制器成为根视图控制器。 希望这可以帮助您。 谢谢。 在main.storyboard中,拖放navigationcontroller。


1
我认为您正在寻找类似于这样的内容:

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

如果您想要新页面的全屏显示:

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

希望这有所帮助 :)

1

Swift 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

0
let vc = storyboard?.instantiateViewController(withIdentifier: "make sure you give id to screen")as! screenviewclass
        self.navigationController?.pushViewController(vc, animated: true)

你告诉我我们必须像这个答案所说的那样,为viewController添加“Storyboard ID”。https://dev59.com/OGAg5IYBdhLWcg3wDHQ3 谢谢! - kujiy

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