How do I have the navigation bar specific to each view controller? On the right side, the navigation bar stays with the view controller, and the left view controller has its own navigation controller. Should I just make a custom transition? Any ideas ?
Add this code in your first viewController
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.setNavigationBarHidden(false, animated: false)
}
Then add navigationBar in your viewcontrollers from storyboad. Or you can add one in viewDidLoad programmatically
Related
I'm trying to Use UINavigationController inside a UITabbarController.
this is my Controllers Structure
-UITabbarController(InitialView)
-tabItemOne-DashboardController
-SomeButtons with StoryboardSegue-To-DifferentViewController
-tabItemTwo-OtherController
-tabItemThree-OtherController
Now I want to show the back button when some StoryboardSegue is performed in DashboardViewController.
Let's say I open the app and can see 4 tabbarItems on UITabbarController, in the first tabbar item I have DashboardViewController, in this DashVC I've 3 4 different buttons to show other viewcontrollers. So far so good, everything is working. but once the child viewcontroller from DashVC is on screen, I want to show a back button on the top as UINavigationController do.
I've tried to put the UINavigationController before UITabbarController but its not showing. i've tried to do embed it in DashboardVC but again its not showing.
Do i need to embed seperate UINavigationController with each of childViewControllers of DashboardVC?
Any help is appreciated.
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.
Consider a storyboard where we have UITabBarController, in it any UIViewController(lets call it VC) embedded in a UINavigationController. We want VC to have a BarButtonItems on its navigation bar. This storyboard is presented by push segue from another storyboard (having another navigation controller).
Everything looks OK in XCode, but navigation bar does not change in VC at the runtime. However when I change presenting this storyboard from push to modal, everything seems to be fine. IMHO it is because of embedding the navigation controller but I do not see any reason why it is not working. Any idea how to fix it legally (presenting by push) and without any pain would be helpful.
Thanks in advance
So I think you will have to employ some code to fix your issue but not much. I built a test project to test this and will attach images along with code.
First if I understand you correctly you have a navigationController push the new storyboard in question. See attached image.
I named the storyboard being pushed because that is what is happening. Then in my storyboard named Push here is the setup.
In the first view controller of the tabbarcontroller I added the below code. Obviously this hides the navigation controller that pushed us here. If you then visit controller number 2 our new navigation controller and items show. If hiding the navigation controller in the tabbarcontroller view controller 1 is not what you want to do then. continue reading.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//or to unhide from returning the opposite ->self.parent?.navigationController?.isNavigationBarHidden = true
self.parent?.navigationController?.isNavigationBarHidden = true
}
If you did not want to hide the navigation controller in the first view controller but when visiting controller 2 you want to see your items then add this to your viewWillAppear and in the first controller in viewWillAppear change the code from true to false.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Do any additional setup after loading the view, typically from a nib.
self.parent?.navigationController?.isNavigationBarHidden = true
}
This hides the parent navigation controller as basically that was covering up your navigation controller in your example. So above hides the parent navigation controller. This is also why presenting modally worked. Your navigation controller was hidden from the start. Hope this helps.
**Edit
If you want the navigation controller in tab 2 view controller but you want to keep the parent in tab one to be able to go back with the back button you can set this in viewWillAppear instead so it would look like this in view controller 1.
//tabcontroller vc 1
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.isNavigationBarHidden = false
}
And in tabcontroller view controller 2 with the item in the bar you could do this.
//tabbarcontroller vc 2 with own navigationcontroller
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.parent?.navigationController?.isNavigationBarHidden = true
}
Finally if you want the back button visible in both controllers but want different right buttons do it programmatically in viewWillAppear
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.navigationItem.setRightBarButton(UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(FirstViewController.editSomthing)), animated: true)
}
And if you want to remove it in the other controller
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.navigationItem.rightBarButtonItem = nil;
}
In Both of the above examples directly above this, we are keeping the parent navigation controller so you would not need to embed your view controllers of the tab controller inside uinavigation controller.
You could also use a combo of the above code if you want the hide/show parent navigation controller in viewWillAppear as well. Some of this is dependent on the view hierarchy you choose now and in the future.
I want to change the navigation's title of a view, which is related to a Tab Bar Controller, which is related to a Navigation Controller (see the picture)
I don't know how to do that.
With a basic view, I just need to do that in the ViewController.swift :self.title="test"
But here, this line changed the tab bar's title, but I want to change the navigation's title.
Main.Storyboard :
On Swift 3, in the UIViewController, override your viewDidAppear method and add this code snippet:
if let tabController = self.parent as? UITabBarController {
tabController.navigationItem.title = "My Title"
}
Use need to use this property:
self.navigationItem.title = "someTitle"
According to Apple best practices you should not have a tab bar controller contained inside of a navigation controller, rather you should have the view controller for each tab that requires one to be inside of it's own navigation controller.
There are various issues that can arise from having a tab bar controller contained within a navigation controller.
When implemented according to their standards you can set the title using self.title
An app that uses a tab bar controller can also use navigation controllers in one or more tabs. When combining these two types of view controller in the same user interface, the tab bar controller always acts as the wrapper for the navigation controllers.
https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/CombiningViewControllers.html
Embed UINavigationController in your storyboard and put:
navigationBar.topItem.title = "Nav title"
I also had difficulty to change a navigation bar title of a child view controller. The solution was:
#IBOutlet weak var navigationBar: UINavigationBar!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationBar.topItem!.title = "Pickup Address"
}
For Swift 3+
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationItem.title = "Title"
}
I have a parent TableViewController and a child ViewController all within the context of a navigation controller. What I want to happen is for the table view controller to NEVER show the nav bar, and for the view controller to ALWAYS show the nav bar. I hide and show the nav bar within the viewWillAppear func of each subclass, like this:
table view controller:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true);
navigationController?.navigationBar.hidden = true
UIApplication.sharedApplication().statusBarHidden=true
}
view controller:
override func viewWillAppear(animated: Bool) {
self.navigationController?.navigationBarHidden = false
}
This works for the first navigation. When I launch the app, the parent table view controller hides the nav bar, and when I select the first cell, the child view controller dutifully displays the nav bar. However, when I touch 'Back' on the nav bar, and then select the cell again, the view controller is no longer displaying the nav bar.
Is there a better way to do this?
Update - as requested attaching screenshots of XIB and Storyboard. Note that there is no XIB for the parent TableViewController. I am not confident that these screenshot will provide much insight. Especially that of the storyboard. Unfortunately, Xcode only has 2 zoom levels:
1. Too zoomed in to be useful
2. Too zoomed out to be useful
Nonetheless, here you have them:
That should work fine: When your ViewController will appear, the code should get executed every time. Try with an "print" to test if that happens.
First View Controller
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
print("viewWillLoad - Table View")
self.navigationController?.navigationBarHidden = false
}
Second View Controller
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
print("viewWillLoad - Detail View")
self.navigationController?.navigationBarHidden = true
}
Ill use that in some applications too.
I have a UINavigationController and I want its root view controller to hide the navigation bar, so I wrote this in the root view controller's class:
override func viewWillLayoutSubviews() {
self.navigationController?.setNavigationBarHidden(true, animated: false)
}
This effectively hides the navigation bar. This root view controller has a button that pushes a new view controller when tapped. I want this second view controller to show the navigation bar, so in its subclass:
override func viewWillLayoutSubviews() {
self.navigationController?.setNavigationBarHidden(false, animated: false)
}
Navigation bar is then shown, but when I tap its back button and I navigate back to the previous view controller (the one I wanted to hide the navigation bar), for an instant at the top of its view it is shown a black space where the navigation bar should be, and finally the view "goes" to the top of the screen again.
How could I avoid this effect?
Try to set the navigation bar hidden in viewWillAppear.
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated);
self.navigationController?.setNavigationBarHidden(true, animated: false)
}