How to use Navigation Controller inside of UITabBarController with Storyboard on Swift
In Interface Builder:
- Create an
UITabBarController
and set it as the initial View Controller. - Create an
UITableViewController
. - Select the
UITableViewController
and go to themenu bar > Editor > Embed in > Navigation Controller
. - Select your
UITabBarController
and CTRL-drag from it to theUINavigationController
. - Choose
Relationship Segue > view controllers
. - Now, any View Controller you will add in the
UINavigationController
stack will be presented in the sameUITabBarController
.
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:
Use UINavigationController inside UITabbarController
So 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:
- Open Main.storyboard.
- Select last segue in this storyboard(one that navigates to Side storyboard).
- Make sure that you have Attribute Inspector selected. Now change Kind attribute to Present Modally and Presentation attribute to Full Screen.
And second solution can be achieved like this:
- Create new file by selecting File > New > File > Cocoa Touch Class and press Next.
- Change Subclass of: to UITabBarController and name your class to whatever make sense to you.
- Then inside of
viewDidLoad()
paste thisnavigationController?.navigationBar.isHidden = true
in order to hide current navigation bar. - 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 UINavigationController
s, 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 ViewController
s, 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
Implementing Fast and Efficient Core Data Import on iOS 5
Xcode 10: a Valid Provisioning Profile for This Executable Was Not Found
Images Can't Contain Alpha Channels or Transparencies
Dashed Line Border Around Uiview
How to Set the Full Width of Separator in Uitableview
How to Dismiss Keyboard iOS Programmatically When Pressing Return
Simply Mask a Uiview with a Rectangle
iOS Autolayout: Two Buttons of Equal Width, Side by Side
Uiview Vertical Flip Animation
How to Make iPhone Vibrate Using Swift
Uibutton Touch Is Delayed When in Uiscrollview
Swift Modal View Controller with Transparent Background
How to Open Maps App Programmatically with Coordinates in Swift
Is There a Public Way to Force Mpnowplayinginfocenter to Show Podcast Controls
Crashlytics Is Not Sending Crash Report from Iphone