UINavigationController without navigation bar? - ios

I have a universal app, and on the iPad version I'm using UISplitViewController to create an interface similar to the Mail app.
I was having trouble pushing new Detail views, so I decided to use a UINavigationController so I could just push and pop views as needed. However, I do not want to use the navigation view or a toolbar. But no matter what I do, I can't hide the navigation bar.
I've tried unchecking "Shows Navigation Bar" in IB, and I've also tried setting:
[self.navigationController setNavigationBarHidden:YES];
in the viewDidLoad/viewDidAppear/viewWillAppear. I've also tried it in each of the views that will be pushed. Nothing works.
Is there something I'm missing here? Is it possible to have a UINavigationController without a toolbar or navigation bar?

You should be able to do the following:
self.navigationController.navigationBar.isHidden = true //Swift 5
where self.navigationController is (obviously) an instance of UINavigationController. Seems to work for me, but I only briefly tested it before posting this.

In Xcode 4.3.2:
Select the navigation controller in the storyboard
Select the Attributes Inspector in the (right) Utilities panel
Under the Navigation Controller category you have two check boxes:
[] Shows Navigation Bar
[] Shows Toolbar
Worked for me...

If you want no navigation bar, and you want the content to be adjusted up to where the navigation bar normally would be, you should use
self.navigationController.navigationBarHidden = YES;
This gives you a result like this:
Whereas self.navigationController.navigationBar.hidden = YES; gives you a space where the navigationBar should be. Like this:

Swift 4
I hide it in viewWillAppear
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.isNavigationBarHidden = true;
}
Then you can put it back when you push a segue (if you want to have the back button on the next view)
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
self.navigationController?.isNavigationBarHidden = false;
}

Swift 3 Programmatically
self.navigationController.isNavigationBarHidden = true
or
self.navigationController.navigationBar.isHidden = true
Note: I didn't see a difference between these two approaches testing on iOS 10.

All these answers still leave a space at the top for the status bar - add this line to remove that as well:
navController.navigationBar.isHidden = true
navController.accessibilityFrame = CGRect.zero

Related

Two NavigationBar Showing

Hi I am new to Swift and am trying to build an app with multiple Views..
My first View(initial view) is embedded in navigation controller.
My Second View is embedded in Tab Bar Controller
My Third View is again embedded in a Navigation Controller.
The problem is that on my third view I see to navigation Controller with the top one taking me back to First View and the below one taking me to Second View.
Is it an incorrect way of doing this? I want to get rid of navigation bar that came from 1st view.
Thanks in anticipation.
PS : I had initially not attempted Navigation Bar on 3rd View.. but the problem was that I am also not able to map Bar Button Item and hence to embed the 3rd View too in a separate Navigation Controller
While it shows perfect in Xcode.. it shows 2 NavBar on the simulator
Not an elegant solution but still this can solve your problem. On your controller embed to UITabBarController where you have added Next Button. Add the below code on that controller class.
On ViewWillappear add show nav bar and on viewDidDisappear hide nav bar as shown in below code
ON viewWillAppear:
override func viewWillAppear(_ animated: Bool) {
self.navigationController.navigationBar.isHidden = false
}
ON viewDidDisappear:
override func viewDidDisappear(_ animated: Bool) {
self.navigationController.navigationBar.isHidden = true
}

Navigation bar buttons set during viewDidLoad don't appear until after view has appeared in iOS 11

In iOS 10, I could determine the list of navigation bar buttons I want to appear in viewDidLoad, and they would appear in the navigation bar as the view controller transitioned in.
In iOS 11, I can no longer do this. Whatever navigation bar buttons were set in interface builder are displayed as the view controller transitions in, and my custom list of buttons are not displayed until after the view finishes sliding in. Updating the buttons in viewWillAppear does not help.
Is this simply a bug in iOS 11, or is there something else I should be doing? Is there a workaround so I can continue to display buttons while the screen loads?
In the following example, I have set a button "Default Button" in the storyboard, and override it with an "Edit" button in viewDidLoad. The project is available on Github.
iOS 10
iOS 11
It looks like the issue is that navigation bar icons displayed during the transition appear to be fixed when the view controller is passed off to the navigation controller. By the time that viewDidLoad is called, the icons have already been fixed.
In order to fix this, we need to update the navigation bar icons on the view controller's navigationItem before the view controller is pushed onto the navigation controller stack.
One way to do this would be to setup the navigation bar icons in awakeFromNib. This is what #Joe's answer was effectively doing, because apparently viewDidLoad is called from awakeFromNib when isViewLoaded is true during awakeFromNib.
However, doing this in awakeFromNib prevents you from taking into account any properties set on the view controller in prepareForSegue. So another option (and the one that I am using) is to force the entire view to load in prepareForSegue by adding the line _ = controller.view after setting any desired properties.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
...
_ = controller.view
}
}
}
Move your Edit barButton code from viewDidLoad to isViewLoaded method as below.
override var isViewLoaded: Bool {
self.navigationItem.rightBarButtonItem = self.editButtonItem
return true
}
Output:
Note: Above code will fix the transition delay issue. Really, don't have much to explain why this happening. I experienced similar issue in iOS 10 as well NavigationBar delay updating barTintColor iOS10. It could be another bug in iOS11.
PS:
After reading Apple Doc about isViewLoaded and comparing other view loading methods. Its all about loading memory upon view loads.
You don't really need to move you barButton code at all.Just implement the isViewLoaded method and return to true as below:
override var isViewLoaded: Bool { return true}

how to hide tab bar when push and show tab bar when back

I want
view controller 1: tab bar is showed
view controller 2: tab bar is showed
view controller 3: tab bar is not showed.
I wrote
// prepareForSegue in view controller 1,
let upcoming = segue.destinationViewController as! viewcontroller3
upcoming.hidesBottomBarWhenPushed = true
// prepareForSegue in view controller 3,
let upcoming = segue.destinationViewController as! viewcontroller2
self.hidesBottomBarWhenPushed = true
When I go to view controller 3 from view controller 1, tab bar is not showed. Then, I go to view controller 2 from view controller 3, tab bar is showed. But when I tap back in view controller 2, tab bar is showed in view controller 3. self.hidesBottomBarWhenPushed = true does not make sense to me. But, I couldn't figure what I should do to fix that. Any suggestions? Thanks.
The way to hide the tab bar is - In the place where you are pushing the next view controller do that:
self.hidesBottomBarWhenPushed = true
self.navigationController?.pushViewController(controllerToPush, animated: true)
self.hidesBottomBarWhenPushed = false
This will make sure the tab bar is hidden for the pushed view and when you pop back the bar will show again. No back button logic, no viewDidLoad or similar, nothing else. This should be enough.
The same should work for objective-c
Now ( 21/02/2018 ) you can also check the option in the Storyboard for each controller that you do not want to show the bottom bar. This will help clean up the code and you do not need to set anything in the controller that you are pushing from.
Edit: That solved the problem.
It makes sense that the tab bar is appearing because when going clicking back from VC2 to VC3, nothing is telling VC3 to hide its Tab Bar.
I think you have 2 solutions here (but haven't tested any):
You can try doing something like this guy did. He added the hidesBottomBarWhenPushed logic in BackButtonPressed Handler.
In VC3, do self.tabBarController?.tabBar.hidden = true in ViewDidLoad or viewWillAppear
#stan has almost the right answer. As he mentioned, you want to set to set hidesBottomBarWhenPushed = true if you want the bottom bar to be hidden. However, you should set it on the controller to be pushed as follows.
controllerToPush.hidesBottomBarWhenPushed = true
self.navigationController?.pushViewController(controllerToPush, animated: true)
Set hidesBottomBarWhenPushed = true in the controller that you want to hide.
For hide all controllers put into prepare for segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
segue.destination.hidesBottomBarWhenPushed = true
}

Adding a navigation controller programmatically for the second VC

In my storyboard, I have setup a navigation controller points to my MainVC, and it works just fine.
And now, I'm trying to add another view called "HelpVC", and I created one in the storyboard. It automatically shows the navigation bar on the top.
(MainVC segues to HelpVC)
However, I did everything else in code.
I had initWithView in the HelpVC which draws out the interface, BUT the navigation bar does not show up, so I can't go back to that previous view controller.
How do I make sure that the navigation bar shows up and works just like other view controllers? (segue back to the last view?)
It is not very clear from the post, but as I understood, you may want to try:
override func viewWillAppear(_ animated: Bool){
super.viewWillAppear(animated)
self.navigationController?.isNavigationBarHidden = false
}

swift hiding navbar in mmdrawercontroller

I have created a slidout menu for kmy app with mmdrawercontroller from github.
It all works perfectly but i can't get rid of the nav bar at the top. it is overlapping part of my many but also shows up on all other pages. I need it gone. i have found the following code
navigationController?.setNavigationBarHidden(navigationController?.navigationBarHidden == false, animated: true)
But i have no idea where to place it. I tried it in appdelegate, in the leftsliderviewcontroller, in the button who invokes the mmdrawercontroller. But nothing seems to work.
Also in code that comes with the mmdrawercontroller i can't find anywhere a bool for this setting.
Can any one show me how to hide this navigationbar.
thanks.
If you want to hide your UINavigationBar in some UIViewControllers the you need to call self.navigationController?.navigationBarHidden = true in your viewWillAppear like in the following way:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBarHidden = true
}
And the above code hide your UINavigationBar. I hope this help you.

Resources