1

i have a tableview and i want to go to another vc when one of rows tapped. my didSelectRowAtIndexPath function is as below. print command works and shows the right clicked row. but when i use self.navigationController?.pushViewController it does not go to vc with playVideo storyBoardId. after changing it to presentViewController it works. what's wrong about my code that push doesn't work?

thanks

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    print("clicked " + String(indexPath.row) )
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewControllerWithIdentifier("playVideo") as! PlayVideoViewController

    vc.id = self.video[indexPath.row].id

    // Present View as Modal
    //presentViewController(vc as UIViewController, animated: true, completion: nil)
    // Push View
    //self.navigationController?.pushViewController(vc, animated: true)
}
Hos Ap
  • 1,168
  • 2
  • 11
  • 24
  • 2
    PlayVideoViewController is not a root of navigation controller so the pushViewController method will not run. You need to add navigation controller by going to your storyboard, select PlayVideoViewController, at top menu select Editor -> Embed In -> Navigation Controller. Now your PlayVideoViewController will become root of navigation controller and the pushViewController should works fine. – muazhud Aug 04 '16 at 20:10
  • @muazhud i did it same as you and Bseaborn said. but still it's not working – Hos Ap Aug 04 '16 at 20:15
  • Here is my answer for the same https://stackoverflow.com/a/56199240/1371853 – swiftBoy May 18 '19 at 13:09

3 Answers3

6
  • Its because the view controller you are currently in may not have a navigation controller.
  • You cannot push a view controller without having a UINavigationController.
  • If your requirement is to push a view controller, then perform the following steps.

    1. Embed a navigation controller for the current view controller.(Open storyboard -> Choose your view controller -> Choose "Editor" -> "Embed in" -> UINavigationController)
    2. Now your code

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

will be working fine.

Bharath
  • 2,064
  • 1
  • 14
  • 39
  • i thought it only needs nav controller on destination. big mistake! thanks for your clear answer – Hos Ap Aug 04 '16 at 20:24
  • @Bharath, how to do this programatically? – Shyam Sep 07 '17 at 16:08
  • @Shyam: To illustrate it programatically, lets assume that you are in FirstViewController & want to navigate to SecondViewController in that case first you have to embed the FirstVC.. in a navigation controller like (let navController = UINavigationController.init(rootViewController: FirstVC..)), then you can present this navigation controller. Then inside the FirstVC you can call (self.navigationController?.pushViewController(SecondVC, animated: true)). – Bharath Sep 29 '17 at 12:22
  • @Bharath, thanks. Guess, it might not work, because, I'm developing an iMessage only app. And, it is not a proper `UIViewController`, rather a child, with it's one limitations. – Shyam Sep 29 '17 at 15:11
  • nice i mi case use wfk programatly and this is nil je – Bruno Sosa Fast Tag Jul 31 '19 at 01:41
2

Make sure that your ViewController is indeed built on a NavigationController. Try forcing the line:

self.navigationController!.pushViewController

if it crashes, you know there is not nav set up. Or you could just check in your storyboard but this is a quick way to tell.

Bseaborn
  • 4,347
  • 2
  • 14
  • 9
  • it crashed. unexpectedly found nil while unwrapping an Optional value. but it has a navigation controller. i don't get it why it says nil – Hos Ap Aug 04 '16 at 20:05
  • 1
    I'm not exactly sure of your setup. But remove the navigationcontroller from storyboard, tap on the viewController you would like to be embed in the nav. Go to Editor -> Embed In -> Navigation Controller – Bseaborn Aug 04 '16 at 20:07
0

I dont know why are you doing it like this. I think its unnecessarily complicated.

This should by your function didSelectRowAtIndexPath:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    self.performSegueWithIdentifier("playVideo", sender: tableView)
}

Then you can specify as much segues as you want in this function:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if (segue.identifier == "playVideo") {
        let indexPath:NSIndexPath = tableView.indexPathForSelectedRow!
        let PlayVideoViewController = segue.destinationViewController as! PlayVideoViewController
        //you can pass parameters like project id
        detailVC.projectID = ids[indexPath.row]
    }
}

Your segue has to be named like this in interface builder:

named segue

Boomerange
  • 616
  • 1
  • 10
  • 18