I have a tab bar with a navigation controller in one of the tabs. Currently the root view of the navigation controller doesnt have the nav bar showing and animates nicely into the subviews by
- (void)viewDidLoad {
...
[self.navigationController setNavigationBarHidden:YES animated:NO];
...
}
and
- (void)viewWillAppear:(BOOL)animated {
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
But of course changing tabs initiates the viewWillAppear function and so as I go back to the root view the navigation bar slides away, rather than just not being there.
Is there a way that I can hide the nav bar on the root view without animating it except for when appearing from a subview on the navigation stack?
The (BOOL)animated parameter on viewWillAppear:animated. When changing Tabs, it will come as NO, since the animation is immediate. On the other hand, if it's being pushed or popped from the navigation stack with animated:YES, then it will come as YES.
Although this looks like a hack, it's the correct way: you don't need to figure out who was the caller, instead, focus on the fact that if your view controller will appear animated, you have time to do your own animations, if not, screw it, show (or in this case, hide) everything immediately.
Try showing/hiding the bar in the UINavigationController's delegate's navigationController:willShowViewController:animated: method, depending on whether the view controller being shown is your root view controller.
What if you set a boolean variable in your application delegate and in set that boolean accordingly in subviews as 0 and in other views as 1. And in your viewwillappear, according to your variable's value, you can set the animation.
Related
A UINavigationController's navigationBar will initially show the correct UINavigationItem, but then will revert to the previous UINavigationItem every time a UIViewController is pushed onto the stack.
Steps to Reproduce:
Push a UIViewController onto a UINavigationController stack
Set navigationBarHidden = YES on the navigation controller
Push another view controller onto the navigation stack.
Begin an interactive pop transition and then cancel it.
Pop back to the previous view controller
Set navigationBarHidden = NO on the navigation controller
Attempt to push a view controller onto the stack
Looks like -[UINavigationBar _cancelInteractiveTransition] is getting called, even on push transitions after getting into this state? I can set a breakpoint on that symbol, and the navigation bar shows the correct navigation item before it and the wrong navigation item afterwards.
But what I want is that the navigation controller's navigation bar should display the current topViewController's navigation item.
#interface UINavigationController (Private)
- (void)_cancelInteractiveTransition:(float)arg1 transitionContext:(id)arg2;
#end
- (void)_cancelInteractiveTransition:(float)arg1 transitionContext:(id)arg2
{
BOOL hidden = self.isNavigationBarHidden;
if (hidden) {
[self setNavigationBarHidden:NO animated:YES];
}
[super _cancelInteractiveTransition:arg1 transitionContext:arg2];
if (hidden) {
[self setNavigationBarHidden:hidden animated:YES];
}
}
I recently ran into this issue on iOS10 and I'm sure it was there on iOS9, assuming we still supported it. It turned out that the issue was that at the start of the interactive transition we were setting navigationController.navigationBarHidden=NO and then when it was cancelled forgetting to set it back to navigationController.navigationBarHidden=YES. It seems like the navigation bar doesn't like to be unhidden twice in a row. I would imagine that its the same for setting it to hidden twice in a row as well. The good news is that this was not an issue with iOS11.
I've got an iOS app that's using a table view with a search bar added to the table view. When a row is tapped, I push another view controller that shows the details of the row that was tapped.
Our table view and detail view both hide the navigation bar.
When the search bar is not active, the navigation bar is disabled on the detail view controller, which is expected.
However, when search is active, the navigation bar shows up on the detail view controller. From what I've read, that's the default behavior for any transitions that occur when search is enabled. Is this accurate?
If so, is there anything I can do to hide the navigation bar? More generally, is there anything I can do to have the push of the detail controller behave the same way regardless of whether search is active or not?
This works
-(void)viewDidLayoutSubviews
{
self.navigationController.navigationBarHidden = YES;
self.navigationController.navigationBar.translucent = YES;
}
In your detail view controller try putting :
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
Link to doc
I have two UIViewControllers, A and B.
A is hiding the UINavigationBar and B is not.
When animating (with the default animation) from A to B, the navigation bar has to become visible. The navigation bar just pops in at some point (viewWillAppear or viewDidAppear) instead of sliding in with the UIViewController B.
When going back from B to A, the navigation bar is smoothly sliding back out.
How can I achieve the desired effect when animating from A to B?
In ViewController B, one has to simply do:
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear: animated];
[self.navigationController setNavigationBarHidden: NO animated: YES];
}
I wasn't aware that this also controls the animation while doing a full view controller transition. I thought it only controls animation the navigation bar out to the top and back in.
You can try the following:
Use a instance variable to do this:
self.navigationController setNavigationBarHidden:hide animated:animated];
_shouldHideStatusBar = hide;
And implement the following function:
- (BOOL)prefersStatusBarHidden{
return _shouldHideStatusBar;
}
The setNavigationBarHidden:animated function will automatically call prefersStatusBarHidden function. If it doesn't you can call it with the following UIViewController's method:
[self setNeedsStatusBarAppearanceUpdate];
And of course you can choose your status bar hiding animation style with:
- (UIStatusBarAnimation) preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationSlide;
}
Let me know if this helps. Good luck!!
(I got this answer here: How to slide in/out statusBar and navigationBar simultaneously?)
I am using UINavigationController to direct some view controllers.In some view controller, I don't want to use UINavigationBar, but in some others i may use. Now I am try to pop one view controller using UINavigationBar to its previous one which hide UINavigationBar. But when poped, there is one wired black space under screen. After you rotate the screen, the space will disappear.
the normal view controller A should be like this:
when press the text button, a view controller B will be pushed, which is as followings:
when click back button on the navigation bar. A will come out.but there is a black space at the bottom.
If rotate the screen, the space will disappear. And also in A's - (void)viewWillAppear:(BOOL)animated method i hide the navigationbar and let the screen autorotate.
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
[super viewWillAppear:animated];
[self willAnimateRotationToInterfaceOrientation:[UIApplication sharedApplication].statusBarOrientation duration:0];
}
whats wrong with this situation? Any help will be appreciated.
I add setNavigationBarHidden: method in the back button action method. it works. If i add this method in viewWillDisappear: method or others, it seems it doesn't work. The navigation bar will have effect on next appear view controller. which means, there will be a black space in the next view controller in the navigation stack.
Finally, i add a action method for the back button and setNavigationBarHidden:YES in the method, which is as follows:
- (void)backBtnClicked:(id)sender
{
[self.navigationController popViewControllerAnimated:NO];
[self.navigationController setNavigationBarHidden:YES];
}
I have a main view controller that lists a bunch of items, and when they tap on one of the items it segues them to the next view. However, in the next view, I don't want the navigation bar to be there, I only want it in the first view (I'm using a UIToolBar for the navigation bar, kind of like in iBooks).
How exactly do I go about achieving this? If I remove the main view controller from the navigation controller completely (unembedding, effectively) I can implement the nav bars selectively, but this solution doesn't allow segues, so it's no good.
My other solution was to call self.navigationController.navigationBarHidden = YES; in viewDidAppear for the second view, but with this, the UIToolBar that I added in my storyboard is pushed under the navigation bar that hasn't been hidden yet, and then when it does get hidden, it disappears and the UIToolBar "falls down", which is a pretty gross effect to the user.
What would be the best way to go about getting this effect?
The best way to do that is the following. In you viewWillAppear: in the first (rootViewController) of your UINavigationController, you set:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
and then in you viewWillDisappear, you the the opposite:
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
This way should work without nothing 'ugly' happening to the user.