Search code examples
iosuinavigationcontrollersegueuistoryboardsegue

Segue and navigation controller interaction


I have a segue set up from a main view controller to a detail view controller, but when it shows, the navigation bar remains the same as the source view - a "close" button and the main title. I'm expecting to see a "Back" button and the title for the detail screen I'm opening (I set the title in prepareForSegue). Xcode's editor shows a back button there, which is apparently triggered by connecting the segue.

More detail on the setup:

  • The main screen is a navigation controller with a tab controller inside. The two tabs display different data but use the same table view controller class.
  • Each tab contains a navigation controller with a table view controller.
  • Each table view controller has a Show segue to the detail view controller.
  • When a particular table item is tapped, the table view controller calls performSegue(withIdentifier:,sender:)
  • The table view controller has prepareForSegue to pass data to the detail controller, and that much is working fine: the data shows up in the detail table.

enter image description here

The prepareForSeque code:

override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
  switch segue.identifier {
    case SegueID.stringList:
      guard let listController = segue.destination as? StringListViewController,
            let indexPath = tableView.indexPathForSelectedRow,
            let stringListField = model.sections[indexPath.section].fields[indexPath.row/2]
                as? ListField<String>
      else { break }

      listController.strings = stringListField.values
      listController.navigationItem.title = stringListField.name
    default:
      break
  }
}

Curiously, Xcode does not show a Navigation Item for the detail view. I tried changing its Presentation from Full Screen to Current Context, but that made no noticeable difference.

How do I get this detail view to display its own navigation item and show a Back button?


Solution

  • From your screen shot it seems that the issue might be you have the tabBarController inside a navigationController.

    You should use the TabBarController as the root view controller (arrow should point to it) and it shouldn't be embedded inside the stack of a navigation controller specifically it shouldn't be a navigationController's rootVC.

    Read here Apple -NavigationController rootViewController

    rootViewController The view controller that resides at the bottom of the navigation stack. This object cannot be an instance of the UITabBarController class.

    Your below comments said that you rearranged everything by setting the tabBarVC as root to the application (arrow pointing to it) but it still didn't work. It's hard to identify the issue.

    You should use print statements to find out which nav controller is doing the pushing, it might help you arrow down the problem.

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // is this the very navController that has the tabBar as root or is this the one of the other ones?
        print("viewDidLoad: \(navigationController?.viewControllers.description as Any)") // this should print everything currently on the stack
    }