How to Use Navigation Controller Inside of Uitabbarcontroller with Storyboard on Swift

How to use Navigation Controller inside of UITabBarController with Storyboard on Swift

In Interface Builder:

  1. Create an UITabBarController and set it as the initial View Controller.
  2. Create an UITableViewController.
  3. Select the UITableViewController and go to the menu bar > Editor > Embed in > Navigation Controller.
  4. Select your UITabBarController and CTRL-drag from it to the UINavigationController.
  5. Choose Relationship Segue > view controllers.
  6. Now, any View Controller you will add in the UINavigationController stack will be presented in the same UITabBarController.

To perform a segue from the first-in-stack UITableViewController connected to the UINavigationController, to another ViewController you must of course first create another ViewController, create a segue to it in Interface Builder, create an identifier for your segue and in your code perform it by calling the appropriate function in Swift like:

optional func performSegueWithIdentifier(_ identifier: String,
sender sender: AnyObject?)

Here's a sample on how your Interface Builder could look like:
Sample Image

Use UINavigationController inside UITabbarController

Sample ImageSo what you need is this

-UITabbarController(InitialView)
-NavigationController -tabItemOne-DashboardController
-SomeButtons with StoryboardSegue-To-DifferentViewController
-tabItemTwo-OtherController
-tabItemThree-OtherController

and in DashBoardController you need to add this code in

override func viewWillAppear(_ animated: Bool) {
self.navigationController?.navigationBar.isHidden = true
}

override func viewWillDisappear(_ animated: Bool) {
self.navigationController?.navigationBar.isHidden = false
}

this code is to hide the navigation bar in Dashboard and restoring when pushing another view controller so you back button is not hide.
also if you need the same functionality in the others view controller you should embebed in navigation controllers.

is not exactly your case but all navigation Controller are Childs of the UITabBarController that is the initial viewController.

Viewcontroller's navigation bar is added below navigation controller's navigation bar inside tab bar controller

There is two ways that I found you can resolve this either by presenting tab bar controller modally or hiding navigation bar of a tab bar controller when view loads.

First solution can be achieved like this:

  1. Open Main.storyboard.
  2. Select last segue in this storyboard(one that navigates to Side storyboard).
  3. Make sure that you have Attribute Inspector selected. Now change Kind attribute to Present Modally and Presentation attribute to Full Screen.
    Sample Image

And second solution can be achieved like this:

  1. Create new file by selecting File > New > File > Cocoa Touch Class and press Next.
  2. Change Subclass of: to UITabBarController and name your class to whatever make sense to you.
  3. Then inside of viewDidLoad() paste this navigationController?.navigationBar.isHidden = true in order to hide current navigation bar.
  4. Assign your class to TabViewController in the Side storyboard by selecting TabViewController and changing Class attribute to your class name in Identity Inspector. It should autocomplete when you entering your class name. Press Enter to make sure that you confirm the changes.

Remember to make just one of this two solutions. Which one would it be is up to your needs.

UINavigationController, and TabBarController programmatically (no storyboards)

When combining a UITabBarController and UINavigationControllers, the correct way to set that up is to make the UITabBarController the rootViewController. Each tab of your UITabBarController gets its own UINavigationController. So, if you have 4 tabs, you will create 4 UINavigationControllers.

See: Adding a Navigation Controller to a Tab Bar Interface


Update

Building off of the code you added in your updated question, create a UINavigationController for each of your vc1, vc2, and vc3.

class CustomTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let vc1 = UINavigationController(rootViewController: FirstViewController())
let vc2 = UINavigationController(rootViewController: SecondViewController())
let vc3 = UINavigationController(rootViewController: ThirdViewController())

viewControllers = [vc1, vc2, vc3]
}

}

In each of your ViewControllers, set title to the title you want to be displayed in the navigation bar when that tab is selected:

class FirstViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
title = "First"
self.navigationController?.navigationBar.titleTextAttributes =
[NSFontAttributeName: UIFont(name: "Chalkduster", size: 27)!,
NSForegroundColorAttributeName: UIColor.black]
}
}

View controller inside tab bar controller

Try getting reference of the tabbar viewcontroller :

let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = mainStoryboard.instantiateViewController(withIdentifier: "tabBarcontroller") as! UITabBarController
viewcontroller.selectedIndex = indexofyourvc i.e 0,1 etc

And push with the navigation controller :

self.navController?.pushViewController(viewController, animated: true )

Storyboard navigation controller and tab bar controller

For changing the UINavigationBar title (with no need to create 2 other UINavigationController) you can just use

[self.parentViewController.navigationItem setTitle:@"Title"];

and for adding the right button use

self.parentViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(myRightButton)];

on viewDidLoad method for each UIViewController referenced from your UITabBarController.

If you want to work with "navigation structures" inside your UIViewController from TabItems so you could edit your BUFViewController.m to that:

#import "BUFViewController.h"

@interface BUFViewController ()

@end

@implementation BUFViewController

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.parentViewController.navigationController setNavigationBarHidden:YES];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(done)];
}

-(void)done{
[self.parentViewController.navigationController popToRootViewControllerAnimated:YES];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end

You have to think as your UITabBarController is inside your parent NavigationController, so you want to hide the parent UINavigationBar and show yours.
After that, you'll be able to back to your table using popToRootViewControllerAnimated: on the parent's UINavigationController.

Hope that helps :)

Present View Controller embedded in Navigation Controller apart of Tab bar controller modally

Get the right navigation controller from tabbarController childs

if let nav = tabBarController.viewControllers[tabBarController.selectedIndex] as UINavigationController {

nav.present(newVC, animated: true, completion: {
print("complete")
})
}


Related Topics



Leave a reply



Submit