I have a UITableView embedded in a NavigationController. The cells each link out to a larger information ViewController. For UI purposes, I hide the Navigation Bar on the TableView and show it in the InfoViewController.
The problem I am experiencing is this: upon booting the app, the NavBar is successfully hidden on the TableView. The first time I tap into a cell and open an InfoViewController, the NavBar comes back as expected. I back out of that VC and into the TableView. Again, the NavBar is hidden, as expected. If I tap into another cell, the NavBar is not displayed as expected. NOTE: This happens even when I remove any code to hide the Navigation Bar.
Here are the relevant code snippets:
TableViewController (in ViewDidLoad()):
self.navigationController?.isNavigationBarHidden = true
InfoViewController:
override func viewWillAppear(_ animated: Bool) {
self.navigationController?.navigationBar.isHidden = false
super.viewWillAppear(animated)
}
Why would it work the first time, but not the second. Any help is appreciated!
For clarification:
App opens to TableView:
enter image description here
I click into the TableViewCell to Segue to InfoViewController:
enter image description here
I hit "Back" to go back to TableViewController. NavBar is still hidden. I click on the same cell:
enter image description here
EDITED: Messed up the TableViewController Code. Put = false instead of = true.
Also, I have one more thought, please someone check this for me. The TableViewController is inside a UIContainerView. It is almost as if when I hit "Back" I am exiting the NavigationController flow and I cannot get back in it.
Please try this code its working fine for hiding navigationBar
TableViewController
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = true
}
}
InfoViewController
class InfoViewController : UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.isNavigationBarHidden = false
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.navigationController?.isNavigationBarHidden = true
}
}
Simple hide navigationbar again when the view controller is appear again,
do below code in tableViewController:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.navigationController?.isNavigationBarHidden = true
}
Related
Is there a way to show navigation view on one view and not show it on another at the same time?
The problem: I have two view controllers - table and description view (called on cell click).
Table got a navigation bar, while description view - don't have it.
Table view:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.navigationController?.isNavigationBarHidden = false
}
Description view controller:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.isNavigationBarHidden = true
}
Everything works fine, but when i swipe for half screen back to table (keeping finger on screen, watching both views) - i don't see navigation bar (which works as expected with that code), and when i release finger - whole table view jumps, because nav bar is shown.
Is there a way to keep not seeing nav bar in description view and see it all the time in table view?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: true)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(true, animated: true)
}
You can hide the navigation bar while doing the segue (earlier). If you're doing it programmatically:
yourVCToBePushed.navigationController?.isNavigationBarHidden = true
If you're doing it in the storyboard, do similarly inside prepareForSegue:
let yourVCToBePushed = segue.destination as! YourVCToBePushed (type)
yourVCToBePushed.navigationController?.isNavigationBarHidden = true
You can also create your own "navigationView" inside tableView header, and add buttons there.
If I have a UITabBarController and do this inside one of its view controllers:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
tabBarController?.tabBar.isUserInteractionEnabled = false
}
the first time it shows, I can still change tabs.
If I tap on another tab and tap back on the first tab, then the tabbar is really disabled, but not the first time.
Why? And how do I solve this?
EDIT:
There is one detail I noticed, the tabBarController?.tabBar.isUserInteractionEnabled = false has to be on the second view controller of a navigation controller. In other words:
Say I have that structure
UITabBarController
UINavigationController
UIViewController (1)
UIViewController (2)
UIViewController (3)
So if I add that viewDidAppear code on view controller (2), you can change the tab once, but not the second time (after you navigate to it, obviously).
And there is more, if I go back after navigating to view controller (2), the tab bar becomes "interactable" again, without my setting it to true.
Having a tab bar in view, but not being able to interact with it will probably be confusing and frustrating for the user. And while I don't have the reason or solution for the original question, I have an alternative suggestion:
Hide the tab bar in UIViewController (2):
override func viewDidLoad() {
super.viewDidLoad()
tabBarController?.tabBar.isHidden = true
}
We're putting this in viewDidLoad so it's hidden as soon as the view
appears.
This also requires that you explicitly unhide it in UIViewController (1) for when the user hits the back button. Do it in viewWillAppear since the view was loaded already and we're going back to it.
override func viewWillAppear(_ animated: Bool) {
tabBarController?.tabBar.isHidden = false
}
While I have experienced the same behavior with:
tabBarController?.tabBar.isUserInteractionEnabled = false
..what you CAN do is disable each of the items in the tabBar.items collection, and then re-enable them in the viewWillAppear method of another controller. For example, if you didn't want your users tabbing out of menu #1 once they are inside it, you could do something like this in the subsequent controller(s):
override func viewWillAppear(_ animated: Bool) {
//0th tab items remains enabled as "only choice" for user
self.tabBarController!.tabBar.items![1].isEnabled = false
self.tabBarController!.tabBar.items![2].isEnabled = false
self.tabBarController!.tabBar.items![3].isEnabled = false
self.tabBarController!.tabBar.items![4].isEnabled = false
}
when the user tabs back to first tab (0) (or hits the back button), in that viewController's viewWillAppear method, re-enable the items:
override func viewWillAppear(_ animated: Bool) {
//re-enable tab items
self.tabBarController!.tabBar.items![1].isEnabled = true
self.tabBarController!.tabBar.items![2].isEnabled = true
self.tabBarController!.tabBar.items![3].isEnabled = true
self.tabBarController!.tabBar.items![4].isEnabled = true
}
Now I have a viewController(A) which is root view controller for Navagation Controller followed by Tab Bar Controller, I want to perform segue from it to another viewController(B), totally replace the A.
Therefore I applied show detail(replace), it worked well as what I think in other cases. However in this case, when A segued to B, the navigation bar and Tab bar still existed. Why this happened and how to solve it?
In viewController(A) you have to write
override func viewWillAppear(_ animated: Bool) {
self.tabBarController?.tabBar.isHidden = false
self.navigationController?.navigationBar.isHidden = false
}
and in viewController(B) you have to write
override func viewWillAppear(_ animated: Bool) {
self.tabBarController?.tabBar.isHidden = true
self.navigationController?.navigationBar.isHidden = true
}
I thought showing a screenshot would help understand the issue a bit better.
So the context is the following:
I'm in a navigation controller, on the settings screen of the app (which has a navigation item) and when we tap on the back button, we go back to the main screen of the app (for which I've hidden the navigation bar in the viewWillAppear of the main screen because I'm building a custom header view myself).
At soon as I tap on the back button, the navigation bar disappears immediately and I see a black rectangle appears instead until the animation to display the main screen is completed.
Do you know how I can avoid having this black rectangle appear?
Hope the questions makes sense.
Screenshots
Here is the initial settings screen:
When we tape on the back button, this happens... help :D
I know this piece of code is most likely responsible for the error, but I absolutely need to have the navigationBar hidden on the previous screen.
override func viewWillAppear(_ animated: Bool) {
navigationController?.isNavigationBarHidden = true
}
Have you tried the animated method of hiding the navigation bar setNavigationBarHidden(_ hidden: Bool, animated: Bool)?
For Swift3.0
Add below code in First ViewController
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
navigationController?.setNavigationBarHidden(true, animated: animated)
}
Add below code in Second ViewController
func backButtonPressed() {
navigationController?.setNavigationBarHidden(false, animated: false)
navigationController?.popViewController(animated: true)
}
Add below code in Second ViewController
the color can corresponding your custom
override func viewWillAppear(_ animated: Bool) {
self.navigationController?.view.backgroundColor = UIColor.white
}
I have a ViewController called SourceViewController that is embedded in a NavigationController.
SourceViewController segues to DestinationViewController upon UITableViewCell selection.
I want to hide the navigation bar on SourceViewController, but display it on DestinationViewController in order to show the Back button.
So, in SourceViewController:
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.hidden = true
}
And in DestinationViewController:
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.hidden = false
}
However, when I tap "Back" in DestinationViewController to return to SourceViewController, the navigationBar reappears in SourceViewController
The next 'obvious' step would be to set navigationBar.hidden = false in viewDidAppear in SourceViewController, however this smells for many reasons: mainly DRYness but also when returning to SourceViewController, there is a delay in hiding the navigationBar, and it is visible for a split second.
How do I solve this problem?
I think this will work, hiding the navigation bar. before appearing/disappearing the view.
override func viewWillAppear(animated: Bool) {
navigationController?.navigationBarHidden = true
super.viewWillAppear(animated)
}
override func viewWillDisappear(animated: Bool) {
navigationController?.navigationBarHidden = true
super.viewWillDisappear(animated)
}
Check ViewController lifecycle Looking to understand the iOS UIViewController lifecycle .
When you start the program viewDidLoad is called and everything is ok, but when you go back from detailController, viewDidLoad is not called, just change this line (self.navigationController?.navigationBar.hidden = true) in viewWillApear and everything must be ok.