tabbar issue with navigation controller - objective-c

I am trying to find a way to avoid this but doesn t seem to find it anywhere
I have a tabbar application in Storyboard
inside one of the tabs I have a navigation bar that goes up to three views in a row
if I go to the third view then switch tabs and come back to the same tabs I see the third view and not the first one ... any way to solve this ?
Thanks

implement the below delegate of tab bar in your appDelegate class, dont forget to set delegate of tab bar to your appDelegate or the class in which tab bar is present.
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
[(UINavigationController*)self.tabBarController.selectedViewController popToRootViewControllerAnimated:NO];
return YES;
}
if you are using story board, write the below code in your didFinishLaunching method of your appDelegate, then your delegate method will be called.
UITabBarController* tab = (UITabBarController*)self.window.rootViewController;
tab.delegate = self;
this will do your work, let me know if it doesn't work for you.

Related

How to hide the NavigationBar when i use SWRevealViewController embed in UINavigationController?

When i use SWRevealViewController as initial view or not embedded in UINavigationController the result is as i expected:
but when the SWRevealViewController comes from UINavigationController tee result is:
How can i avoid the NavigationBar presented in the Rear view?
Please add the following code to the viewWillAppear: method of the viewcontroller whose navigation bar you need to hide.
[super viewWillAppear:YES];
[self.navigationController.navigationBar setHidden:YES];
[self.navigationController.navigationBar.backItem setHidesBackButton:YES];
Try, this code for rear view controller
- (void)viewWillAppear:(BOOL)animated
{
self.navigationController.navigationBar.hidden = YES;
}
If you really need Navigation Controller on top of SWRevealViewController:
You got to hide navigation bar from navigation controller of your SWRevealViewController.
U can do this in IB (assuming you are using Storyboards):
Select Navigation Controller in your Storyboard
Open Attributes inspector
Find section "Navigation Controller", uncheck "Shows Navigation Bar"
Next, If you want navigation bard in front view controller, then attach it to separate Navigation Controller. You will have two Navigation Controllers, think on which one you want to push - it will have different effect.

Why UINavigationController keep popping out the top controller

I have UITabBarController, one of the tab points to a UINavigationController. The UINavigationController rootViewController is of class BGProfileView which shows users' profile
At viewDidAppear, I arranged that if users didn't logged in it will push a BGLogin view controller.
[BGLogin alreadyLoggedin:self.navigationController hideBackButton:YES anddoBlock:^{
[self whatToDoAfterLogin];
}];
Now everything is fine but with one minor issue. If I press the tab again, BGLogin will be poped out of UINavigationController.
I have no idea what makes that BGLogin poped out.
If I select a different tab and then click back to the BGProfile tab, this doesn't happen. It just happens when I click the same active tab. So I am in BGProfile tab, and I click that tab again. Basically it happens when I select the active tab that should simply do nothing. In fact, it does do nothing on others.
I put a breakpoint in viewWillDisappear and this is what I see:
As you see, viewDidAppear is called by the main loop. But why the hell the mainloop call viewDidAppear? Usually there is a code saying things like nav popViewController
Chances are there . that your tab bar controller is pushing new navigation controller with root view controller. and you interpreting that it's popping out. When same tab is selected you need to tell your tabBarController to not to do anything explicitly.
Example
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
UIViewController *tbSelectedController = self.tabBarController.selectedViewController;
if ([tbSelectedController isEqual:viewController]) {
return NO;
}
return YES;
}

Is there a way to remove UITabBar/or do something for a UIViewController and ALL other UIViewcontroller added on top of UINavigationBar Stack?

This is the approach I am using:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.tabBarController hideTabBar];
}
-(void) viewWillDisappear:(BOOL)animated
{
[self.tabBarController showTabBar];
[super viewWillDisappear:animated];
}
With this approach if I add something to the navigation stack the UITabBar will be shown again.
What about if I want UITabBar to be only shown when user navigate away to another tab or press back button, so not all cases of viewWillDisappear?
Pushing a UIViewController on top of navigation stack shouldn't change that
You can use NSNotification as well, so whenever you require to hide tab bar. At that moment fire that notification which will show/hide your tab bar.
Benifit of NSNotification is, you can fire that in entire application life cycle, and it does not be specific to any view controller or any class. One can use that independently from any class/view controller.
Hope this is what you are looking for.
Regards,
Mrunal
Do following in your view will appear method
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillDisappear:animated];
self.navigationController.tabBarController.tabBarController.tabBar.hidden=TRUE;
}
This will remove tabbar from the particular controller . and navigation stack will not change.
This is what I did
At viewDidDisappear, I check if self.navigationController is empty. If it's empty I simply know that the view has been poped out of navigationController, which is the only way to get that view out of window hierarchy.

Navigation items for navigation controller in interface builder

- i have a FirstViewController and a SecondViewController, each has its xib
- in the MainWindow.xib i have a UINavigationController, which is connected to IBOutlet
- in the AppsDelegate i call
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
FirstViewController * fv = [[FirstViewController alloc] init];
[navigationController pushViewController:fv animated:NO];
[fv release];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
4) the problem is, when i want to manage Navigation item through interface builder... like for the first view i want to add a button to the right and customize the back text and the title
sure i could do this using code :
(by fv.navigationItem.rightBarButtonItem = ... and fv.title=#"...") but i want to achive this in interface builder
in my FirstViewController.xib and SecondViewController.xib i add a Navigation item and add the a right Bar item
the problem is, it never shows up and the title doesnt alter
if i open MainWindow.xib and add a ViewController (FirstViewController) under the NavigationController (so its listed under it = make it the rootViewController for the NavigationController) and also add Navigation item and Bar Buttom item, whoala, the NavigationBar at the top has the left button
again this would be great... BUT i cannot do the same think for the SecondViewController, because in interface builder, there can be only one rootViewController under the Navigation Controller... and again if i add the Navigation item in SecondViewController.xib it doesnt show up:(
- so ho can i manage the Navigation items and Bar button items for multiple ViewControllers in interface builder
(i looked at most tutorial, but they do it inside the code, by .navigationItem.rightBarButtonItem, what i want to avoid)
ok, the best solution i found
is to design the buttons in Interface builder and link them via Outlet, then in code i simply add them
fv.navigationItem.rightBarButtonItem = myOutletButton;
i didnt find a way to do it just only in interface builder so it gets bind automaticly :(
If u like to do a separate NVC please instaniate it not from main view, do this from different view's separate.

TabBarController NAvigationController and UIViewController

I have the next question:
In my project I have the next:
UItabbarController
....Some UINAvigationControllers....
*(1) UINavigationController
UIViewController (UItableView) - When select one row it goes to...(by push) to:
UIViewController (UItableView) - And here the same than before, for each row i open a new tableview....
My problem is when i click in the tab bar item, I see the viewController view like last time that i saw this, and no reload to the *(1) first view another time( like i would like)
Where I need to write sth for each time that i click in a tab bar item i reload the first view of this tab bar item.
PD: I have the call: [theTableView reloadData]; in method "viewWillAppear".
The thing I'm doing is:
In my navigation Controller I have a View Controller (like tableview) and when i click in one row, in the "didSelectRowAtIndexPath" method I create another View Controller calling "myController" and i push this element like this ( [[self navigationController] pushViewController:myController animated:YES];)
And this for each time i click in one row in the next tables.
Then I think the problem is not to reload the table view in the method viewWillAppear, it's to take out from the screen the next views controller that I inserted to the root one.
I'm rigth?
IN RESUME:
My app has the next:
Tab bar to move between screens
Navigation inside each tab bar (as far as you want), why? because all the tabBarItems show Tables, and if you click in one row you open another table,.....
My problem then is that I would like to come back to the 1st Main table when i click in the tab bar. For the moment the app doesn't do this, it continue in the scree(table view) that was the last visit in this tab. (Is not completely true, because if i click two time, Yes, it comes back but don't enter in the "viewWillLoad" or "didSelectViewController" methods, because i made NSLogs and it doesn't show them).
The sketche can be this:
AppDelegate -> WelcomeScreen ->VideosTableViewController ->RElatedVideosTableViewController -> ..... ..... ....
The 1st thing is to show the Welcome screen (not so important, only some buttons) and in this class i have the TabBArController initialized with "localViewControllersArray" that is a NSMutableArray of NavigationControllers each initialized with one ViewController .
Then when i press one of the buttons in this welcome Screen i sho the tab bar Controller (Shows the VideosTableViewController)
In the next step, when I click in one row, in "DidSelectRowAtIndexPath" I create a RElatedVideosTableViewController, and I push this by "[[self navigationController] push....: "The relatedvideo table view i create" animated:YES];
AND I ALSO HAVE:
Add: UITabBarControllerDelegate
Add:
(void)tabBarController:(UITabBarController*)tabBarController
didEndCustomizingViewControllers:
(NSArray*)viewControllers
changed:(BOOL)changed { }
(void)tabBarController:(UITabBarController*)tabBarController
didSelectViewController:(UIViewController*)viewController
{ if ([viewController
isKindOfClass:[UINavigationController
class]])
{ [(UINavigationController *)viewController popToRootViewController:NO];
[theTableView reloadData];
NSLog(#"RELOAD");
} }
And at the initialization of the class:
[super.tabBarController setDelegate:self];
But in the console I don't see the NSLog I'm making then is not going in this method.
Make your app delegate the tab bar controller's delegate, either in Interface Builder or in code:
- (void)applicationDidFinishLaunching
{
...
self.tabBarController.delegate = self;
}
Then, when the tab bar switches to a different view, you get notified, at which point you pop to the root of the selected nav controller thus:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[UINavigationController class]])
{
[(UINavigationController *)viewController popToRootViewController:NO];
}
}
Each view controller should have its own table view, so I don't know what you are trying to do by the reload.