1
votes

I want to segue from a tableview that is embedded in a navigation controller to another view controller once I clicked on a table cell. I still want that second view controller to be embedded in the same navigation controller. Hence, I created the segue via storyboard.

However, I want to conditionally check after tapping on the cell if the segue should be performed or not.

I already checked out the method shouldPerformSegueWithIdentifier, which would satisfy my needs, but unfortunately, it is executed before the table click handler. If I remove the storyboard segue and just segue via performSegue, my second view controller is not embedded in the same navigation controller anymore.

Any advice?

Here's my code:

// Called on click event on table cell
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
    let app = apps[indexPath.section]
    if app.state == .INSTALLED {
        let inputVC = self.navigationController?.viewControllers[1] as? InputVC
        inputVC?.app = app
        performSegue(withIdentifier: "showAccSync", sender: self)
    } else {
        // show alert
    }
}
3
If you are triggering the segue from the action of the tableview cell then shouldPerformSegue is what you want; but you shouldn't then have any code in didSelectRowAt, or you can ctrl-drag from the orange view controller object in your scene to your next scene and then perform that segue using performSegue in didSelectRowAt - Paulw11
@Paulw11 thank you for the hint. When I change the segue having the orange vc object as the source, the line where I get my inputVC from the navigation controller throws me an out of bounds though - phoebus
Yes. That line doesn't make much sense. What are you trying to achieve with accessing the navigationcontroller stack? If you are trying to access the new view controller, you would do that in prepareForSegue - Paulw11
You get that reference from the destination property of the segue passed to your prepareFor: function. The destination view controller doesn't exist before you have called performSegue - Paulw11
@Paulw11 that did the trick, thank you - phoebus

3 Answers

7
votes

You should start the storyboard segue from the view controller itself instead of a cell. That way, it won't execute automatically if you tap on a cell.

segue from view controller

If you want to push the view controller to the navigation stack without using a storyboard segue, use UINavigationController's pushViewController:

if let secondVc = storyboard?.instantiateViewController(withIdentifier: "Second") {
    navigationController?.pushViewController(secondVc, animated: true)
}
1
votes

Assign storyboard identifier to your InputVC, Say "input_vc". Then instantiate it with storyboard. Then push to your InputVC it would be on same navigation stack.

enter image description here

Add the code in didSelectRow as:

Then instantiate your InputVC with storyboard. Then push to your InputVC it would be on same navigation stack.

guard let inputVC = storyboard?.instantiateViewController(withIdentifier: "input_vc") as? InputVC else { return }
inputVC.app = app
self.navigationController?.pushViewController(secondVc, animated: true)
1
votes

Programmatically, you can do like this

let lvc = storyboard?.instantiateViewController(withIdentifier: "yourViewController") as? yourViewController 
self.navigationController?.pushViewController(lvc, animated: true)