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!
Related
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.
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 have a UITabBarController as the rootViewController in the storyboard of an iPad app.
It contains 3 tabBarItems.
Each item holds a navigationController.So total 3 navigationControllers.
Scenario:
I select the 2nd tabBarItem. Then the 2nd navigationController will become visible on the tabBarController with the view of its associated rootController.
I push some controllers on this visible navigationController.
Now, when I tap of the 2nd tabBarItem ( which is already selected now ), the tabBarController pops-up all the pushed controllers and brings the navigationController to its rootController view.
Question:
How can I stop this behaviour ? A selected tabBarItem should not do any action when the user taps on it again.
If you init the UITabBarController in rootViewController add UITabBarControllerDelegate in rootViewController, and implement this delegate:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
UIViewController* selected = [tabBarController selectedViewController];
if (viewController == selected)
return NO;
else
return YES;
}
Set delegate for your UITabBarController to reach any behavior you want. ( UITabBarControllerDelegate)
And then implement delegate methods
- (id <UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController
animationControllerForTransitionFromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC{
return self;
}
-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
return 0.25f;
}
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
self.transitionContext = transitionContext;
//Custom transition method.
[self executePresentationAnimation:transitionContext];
}
Reference: https://developer.apple.com/library/ios/documentation/uikit/reference/UITabBarControllerDelegate_Protocol/Reference/Reference.html
I have a tab bar controller into a navigation controller. I want to change the navigation controller's root view depending on whether or not a user is logged in. How do I do this? I don't want to put the code in didFinishLaunchingWithOptions: or any other AppDelegate method because it won't be the first thing the users will see.
You're right, its supposed to be:
- (void) goNext {
NextViewController* nextWindow = [[NextViewController alloc] initWithNibName:#"NextView" bundle:nil];
[self.navigationController setViewControllers:[NSArray arrayWithObject:nextWindow] animated:YES];
}
Since you can't pop the root view controller, the following method can be used instead:
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated
Here's a link to the
apple docs for this method.
In my app tabbar contain four tab on
first tab button is their on clicking on that button
it should jump to second tab i haved used.
self.tabBarController.selectedIndex = 1;
it works but requirement is that
on clicking on that button it should pop
to the first viewcontroller of second tab.
thank in advanced
You can check this when going to second tab bar in you appdelegate delegate method is called here you can poptorootviewcontroller
-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
Put following code inside this delegate method.
if ([viewController isKindOfClass:[UINavigationController class]])
{
[(UINavigationController *)viewController popToRootViewControllerAnimated:NO];
}
it working i haved used below code. on button click
self.tabBarController.selectedIndex = 1;
[[self.tabBarController.viewControllers objectAtIndex:1] popToRootViewControllerAnimated:NO];