I knew its a duplicate. But still having an issue and even when tried with possibilities didn't work. Hence posting the same to reach a solution. Hope to get help from you guys.
The initial is embedded inside UINavigationController. For the initial (the landing view) the navigation bar must be hidden. The other views when called from the landing view - must show the navigation bar.
I'm handling the hide & show of navbar in the landing view by overriding the methods of the view as follows:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Hiding the navigationbar hidden for the first page
[[self navigationController] setNavigationBarHidden:YES animated:YES];
}
// Even tried animated:NO & animated:animated
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
// Showing the navigationbar hidden for the first page
[[self navigationController] setNavigationBarHidden:NO animated:YES];
}
While the app loads initially, the nav bar is in hidden state (as expected & working fine). When coming back to the landing view from the child view controller, the nav bar gets hidden after some seconds - the landing view gets loaded on to the ui screen.
I also tried using the navigationcontroller delegate method in landing view: navigationController: willShowViewController: animated:. But unable to reach the solution that i need.
Hence i provided the navigationcontroller delegate in one of my childviewcontroller and checked whether the childcontroller when popped is not in viewcontrollers of the navigationcontroller using if condition. When yes, then i provided the hide option of the navigationbar. but also failed to have the solution.
During surfed, there was a solution to handle with viewanimation. I tried and that too failed.
Again surfed, the solution provided across is to handle the similar issue with viewwillappear & viewwilldisappear. I'm blinked since the way i'm doing is similar to the proposed way. Even then unable to reach a solution.
FYI.. I'm using Xcode 6.3 and deployment target is 6.0 onwards. I'm using storyboard to manage views.
Please help me sort the issue... App loads is hiding the nav bar in landing page. But when landing page is loaded back from a child view then the nav bar gets hidden only after the landing page loaded on to the ui. I do need to get hidden of the nav bar as like when app loads, when the child view pops and the landing view gets loaded on the top of the controller.
If you want to hide navigation bar in the second view then don't try to manage in viewWillAppear and viewWillDisappear because I have faced a lot of problems by trying like that and it also effected the constraints. Just use delegate for navigation controller in appDelegate it is working fine for me.
self.navigationController.delegate = self;
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([viewController isKindOfClass:[LoginViewController class]])
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
} else {
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
}
Use this method:
[navigationController setNavigationBarHidden:YES];
So, if you are in some view controller:
[self.navigationController setNavigationBarHidden:YES];
More clarifications:
UINavigationController has a property navigationBarHidden, that allows you to hide/show navigation bar for whole nav controller.
Let's look at the next hierarchy:
--UINavigationController
----UIViewController1
----UIViewController2
----UIViewController3
Each of three UIViewController will have nav bar since they are in UINavigationController. For example, you want to hide bar into the second (actually it doesn't matter in which one), then write into UIViewController2:
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES]; //it hides
}
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO]; // it shows
}
Overwrite the delegate method in your custom UINavigationController class:
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[self setNavigationBarHidden:NO];
if ([viewController isKindOfClass:[SomeViewController class]])
{
[self setNavigationBarHidden:YES];
}
}
One advantage for putting it in your UINavigationController class is that you don't clutter your UIViewController class with code
Tested and works.
UPDATE
Create a UINavigationController subclass: f.e. MyNavigationController
In AppDelegate.h:
#import "MyNavigationController.h"
#property (nonatomic) MyNavigationController *navigationController;
Then initialise it in AppDelegate.m:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Probably some more code here
self.navigationController = [[MyNavigationController alloc] initWithRootViewController:yourRootViewController];
self.window.rootViewController = self.navigationController;
self.window.backgroundColor = [UIColor blackColor];
[self.window makeKeyAndVisible];
return YES;
}
Then overwrite the delegate method in your custom UINavigationController class
I have little to no experience with storyboards so not really sure how to setup a custom UINavigationController, but this is how I do it in code.
Here's another SO post how to create a custom UINavigationController to use with storyboards.
Related
I have a Tabbarcontroller filled with 5 Viewcontrollers and Navigationcontrollers as I did here:
[self addChildViewController:VC1];
[self addChildViewController:NavigationController;
[self addChildViewController:VC2];
[self addChildViewController:VC3];
[self addChildViewController:VC4];
Now the thing is, that pressing a button on my Tabbar gets me to every ViewController easily, where I can present Xib-Files etc.
But now I want to have a Navigationcontroller, which is shown when pressing a button on my Tabbar. This Navigationcontroller itself has several Viewcontrollers.
I tried this to present my first Viewcontroller inside my Navigationcontroller (this code is from the Navigationcontroller.m):
- (void)viewDidLoad {
[super viewDidLoad];
[self addChildViewController:VC5];
[self presentViewController:VC5];
}
This expectedly did not work and gave me: Application tried to present modally an active controller.
Is there a good way to achieve such a specific goal? I'm struggling with this problem. Thanks in advance!
edit: This is how I set it up in my storyboard. In my programmatic approach the first view controller is not shown.
Instead of adding the VC5 view controller to the NavigationController as a child (unless it's meant to be a child?) add it as the root view controller when you add the NavigationController to the tab bar.
For example in your tab bar code:
[self addChildViewController:VC1];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:VC5];
[self addChildViewController:navigationController];
[self addChildViewController:VC2];
[self addChildViewController:VC3];
[self addChildViewController:VC4];
Apple docs on UINavigationController are here: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UINavigationController_Class/#//apple_ref/occ/instm/UINavigationController/initWithRootViewController:
I have a NavigationController then a TabBarController which has Four Tabs.
I wanted to display Different titles on TopBar when a Different Tab is selected.
One way was to Embed each TabBarItem View into Navigation Controller but for some reason this doesn't seems the correct way, i wanted to apply this via code.
I managed accomplish this by using this code: (Products_ViewController.m custom class)
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UINavigationController *navCon = (UINavigationController*) [self.navigationController.viewControllers objectAtIndex:0];
navCon.navigationItem.title = #"Products";
}
But the problem is now when a tab is clicked First time, it changes the title but then it doesn't. I then applied the same code on -(void)viewDidAppear{} but still the same result.
How can i manage to display navigation top bar title (or run the above code) whenever the tab bar item is clicked or the view is shown?
Thanks!
You could implement the UITabBarControllerDelegate in the Products_ViewController.m class and execute your code in the tabBarController:didSelectViewController: method.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
UINavigationController *navCon = (UINavigationController*) [self.navigationController.viewControllers objectAtIndex:0];
navCon.navigationItem.title = #"Products";
}
In the viewDidLoad method you have to set the delegate to self.
I use following method to disable the Navigation bar throughout the app:
[navcontroller setNavigationBarHidden:YES animated:YES];
But is it possible to disable it only for one ViewController?
Certainly. Whenever you enter a viewcontroller, you can enable or disable for that viewcontroller (just call [[self navigationController] setNavigationBarHidden:YES animated:YES] during viewWillAppear
The nicest solution I have found is to do the following in the first view controller.
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
[super viewWillAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:NO animated:animated];
[super viewWillDisappear:animated];
}
This will cause the navigation bar to animate in from the left (together with the next view) when you push the next UIViewController on the stack, and animate away to the left (together with the old view), when you press the back button on the UINavigationBar.
Please note also that these are not delegate methods, you are overriding UIViewController's implementation of these methods, and according to the documentation you must call the super's implementation somewhere in your implementation.
Hopefully this will resolve your problem.
I have implemented a custom version of a search form that behaves a lot like a UISearchBar with a scope bar (but is actually pieced together programatically for UI reasons). The screen loads with a TextField, you tap in the TextField and the navigation bar animates up off the screen, the text field moves up and a segmented control appears for filtering results.
Anyway, that all works, but when I tap on one of the search results my code pushes a new ViewController. The problem is that new controller gets pushed without a navigation bar (because I used [[self navigationController] setNavigationBarHidden:YES animated:YES] when switching to the search state).
I can show the navigation bar as the new ViewController gets pushed, or even animate it in as the transition to the new ViewController appears - but all those solutions look clunky. I want it to work as if you were using a UISearchBar (actually more like the email app) in that the restored navigation bar appears to just slide in from the right as if it's part of the child view controller.
I'm hoping there'll be a simple fix... thanks
For anyone that comes to this, the solution is to make your controller the delegate of the UINavigationController, then show or hide the nav bar in your delegate methods.
Your controller needs to implement the protocol:
#interface MYSearchController() <UINavigationControllerDelegate>
Then in -(void)viewDidLoad assign your controller as the delegate:
[self navigationController].delegate = self;
Finally, implement a method like this:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if(viewController == self)
{
if(_searchState && ![self navigationController].navigationBarHidden)
{
[[self navigationController] setNavigationBarHidden:YES animated:YES];
}
}
else
{
if([self navigationController].navigationBarHidden)
{
[[self navigationController] setNavigationBarHidden:NO animated:YES];
}
}
}
I need some idea or starting point to the following question:
I have an app which starts with an TabBarView - in some Tabs there are different Views / ViewControllers which are connected by seques.
If the active Tab is changed, i want the (now) open Tab to load the "Start"-View/ViewController of this Tab, not the View/ViewController which was last active on this Tab.
How can i do that?
I suggest you look at using the UITabBarDelegate method: tabBarController:didSelectViewController:
combined with the UINavigationController method: popToRootViewControllerAnimated:
So when the user selects a tab, you can ensure that the navigation begins from the root controller.
EDIT IN RESPONSE TO COMMENT:
It's not an ideal situation, but you can reference the UITabBarController in the app delegate. E.g.:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Get reference to Tab Bar Controller as the root view
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
// Set Delegate
tabBarController.delegate = self;
return YES;
}
You can then implement the UITabBarDelegate method similar to:
-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
// Pop to root if the selected controller is a navigation controller.
if ([viewController isKindOfClass:[UINavigationController class]]) {
[((UINavigationController *)viewController) popToRootViewControllerAnimated:NO];
}
}
I haven't tested this though!