I am building an iphone application.
I have a tabbarcontroller that has 2 tab items. Each tabitem links to a different navigationcontroller. Each navigationcontroller links to a hierarchy of tableviewcontrollers.
When a user clicks on tab 1, then clicks on an item in the table, then clicks tab 2, and then clicks on tab1, the application shows the table that he was just looking at before he clicked on tab2.
How do i get the app to show the first table of tab 1 every time he clicks on tab 1 instead of showing the most recent table he was looking at before leaving tab1?
I would prefer a programmatic solution as opposed to using xcode storyboard. But if none exists, then storyboard solution is fine too.
Call popToRootViewControllerAnimated: on the NavigationController when the TabBarController changes tab that is being displayed.
Try this basic sample to create a UItabBar and UInavigationController for each UItabBarItem from scratch :
in your header file (appdelegate.h) , add this delegate :
#interface AppDelegate : UIResponder <UIApplicationDelegate,UITabBarControllerDelegate>
in the function called "didFinishLaunchingWithOptions" , add this part of code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UINavigationController *navController=[[UINavigationController alloc] init];
m_ViewController1 = [[ViewController1 alloc] initWithNibName:#"ViewController1" bundle:nil];
[navController pushViewController:m_ViewController1 animated:NO];
UINavigationController *navController2=[[UINavigationController alloc] init];
m_ViewController2 = [[ViewController2 alloc] initWithNibName:#"ViewController2" bundle:nil];
[navController pushViewController:m_ViewController2 animated:NO];
UITabBarController *mtabBarController = [[UITabBarController alloc] init];
mtabBarController.view.frame = CGRectMake(0, 0, 320, 460);
// Set each tab to show an appropriate view controller
[mtabBarController setViewControllers: [NSArray arrayWithObjects:navController1,navController1,navController2, nil]];
self.window.rootViewController = mtabBarController;
mtabBarController.delegate = self;
[self.window makeKeyAndVisible];
return YES;
}
Then in this function , don't forget to add the popToRootViewControllerAnimated function :
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
[m_ViewController1.navigationController popToRootViewControllerAnimated:YES];
[m_ViewController2.navigationController popToRootViewControllerAnimated:YES];
return YES;
}
in my appdelegate.h file, I changed the line
#interface wscAppDelegate : UIResponder <UIApplicationDelegate>
to
#interface wscAppDelegate : UIResponder <UIApplicationDelegate,UITabBarControllerDelegate>
Then in my CustomTabBarController in the viewDidLoad function i added these lines:
wscAppDelegate *appDelegate = (wscAppDelegate *)[[UIApplication sharedApplication] delegate];
self.delegate = appDelegate;
Then in appdelegate.m file, I added this function
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
for(int c=0; c<[tabBarController.viewControllers count]; c++)
{
UINavigationController * navcontroller = [tabBarController.viewControllers objectAtIndex:c];
[navcontroller popToRootViewControllerAnimated:YES];
}
return YES;
}
Related
This question already has answers here:
Prevent automatic popToRootViewController on double-tap of UITabBarController
(5 answers)
Closed 9 years ago.
I'm having some issues pushing a view, using the navigation stack.
The problem I encounter is that after touching a tab bar item a view controller is pushed into the navigation stack (from a view controller named FirstViewController) like so :
- (void)viewDidLoad
{
[super viewDidLoad];
svc = [[SecondViewController alloc] init];
[self.navigationController pushViewController:svc animated:YES];
}
That works as expected, but the actual issue arises when touching the same tab bar item again.
When that happens the current view ( the SecondViewController that was previously pushed) is removed, it's like I would be touching the "done" button.
I can not trace where or why that's happening.
EDIT: This is how I set up the tab bar, view controllers and navigation:
#implementation AppDelegate
#synthesize HomeViewController, FirstViewController, SecondViewController, ThirdViewController, SettingsViewController, tabBarController, window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
FirstViewController *firstViewController = [[FirstViewController alloc]
initWithNibName:nil bundle:nil];
UINavigationController *firstViewControllerNav = [[UINavigationController alloc]
initWithRootViewController:firstViewController];
SecondViewController *secondViewController = [[SecondViewController alloc]
initWithNibName:nil bundle:nil];
UINavigationController *secondViewControllerNav = [[UINavigationController alloc]
initWithRootViewController:secondViewController];
ThirdViewController *thirdViewController = [[ThirdViewController alloc]
initWithNibName:nil bundle:nil];
UINavigationController *thirdViewControllerNav = [[UINavigationController alloc]
initWithRootViewController:thirdViewController];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[firstViewControllerNav,
secondViewControllerNav];
UITabBar *tabBar = tabBarController.tabBar;
UITabBarItem *tabBarItem1 = [tabBar.items objectAtIndex:0];
UITabBarItem *tabBarItem2 = [tabBar.items objectAtIndex:1];
[self.window setRootViewController:self.tabBarController];
[self.window makeKeyAndVisible];
return YES;
}
Touching a tab bar item twice will cause the navigation controller to pop back to the root view controller. This is expected and built-in behavior.
To prevent this you will have to use the tabBarController:shouldSelectViewController: method of the UITabBarControllerDelegate protocol.
I believe something like this will do the trick:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
return viewController != tabBarController.selectedViewController;
}
I apologize for asking two similar questions but I don't think I worded it correctly the first time and am still struggling to find the answer.
I am in a viewcontroller that is in a project containing a tabBarController. I want to switch from the viewController to one of the viewcontrollers contained in the tabbarcontroller. The problem is it either doesn't show up at all or if I present the normal viewcontroller there is no tab bar.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIViewController *viewController1 = [[[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil] autorelease];
self.tabBarController.viewControllers = #[viewController1, viewController2,viewController3);
}
I want to switch from my Tag view controller to FirstViewController
Tag.m
-(IBAction)save:(id)sender{
FirstViewController*vc =[[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
[self.tabBarController.viewControllers popToViewController:vc animated:YES];
}
Update:
I solved this by adding my ViewController to a TabBar within my .m file then
[_tabBarController setSelectedIndex:0];
[self presentViewController: _tabBarController animated:YES completion:NULL];
Thanks for the responses I got on this question.
You can change rootViewController property of mainWindow of AppDelegate some thing like this.
AppDelegate * appDel = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[appDel.window setRootViewController:tabBarController];
Enjoy..
I'm having trouble coding a button to go to the previous page. I was able to do it to go to the next page thinking if I did the same thing but changed it a bit it would work in reverse. Unfortunately, I come up with a lot of errors I can't resolve because it won't allow me to use the release function.
This is this the code that helps it to work going to the next page fine:
#import "ViewController.h"
#implementation ViewController
-(IBAction)btnClicked:(id) sender
{
//add the view of the view controller to the current View---
if (menuView==nil) {
menuView =
[[MenuView alloc] initWithNibName:#"MenuView"
bundle:nil];
}
[self.view addSubview:menuView.view];
}
-(void)dealloc {
[menuView release];
[super dealloc];
}
How do I do it so that a back button will go to the previous page though.
It's pretty simple, use this :
-(IBAction)back:(id) sender
{
[menuView.view removeFromSuperview];
}
But, I would suggest not using addSubview: for many views as it would be complex way to do. Use UINavigationController as #Paul.s suggested.
The way you are doing this is not quite correct and I would suggest doing some reading to get familiar with iOS programming.
Your program structure should be: create a navigation controller (2) to manage the stack of view controllers giving it a viewController (1) to act as it's root.
// AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// 1
FirstViewController *firstViewController = [[FirstViewController alloc] init];
// 2
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
[firstViewController release]; firstViewController = nil;
self.window.rootViewController = navigationController;
[navigationController release]; navigationController = nil;
[self.window makeKeyAndVisible];
return YES;
}
This will display your first view controller inside a UINavigationController. A UINavigationController is responsible for managing a stack of UIViewController's and giving you UI to navigate back down the stack as well as calling all the appropriate presentation related methods on a UIViewController at the correct times e.g. viewDidLoad. You should check out The View Controller Programming Guide for lots of info
Then inside your first view controller you do something like this to respond to the button:
- (IBAction)buttonClicked:(id)sender;
{
SecondViewController *secondViewController = [[SecondViewController alloc] init];
[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release]; secondViewController = nil;
}
This creates a new view controller and pushes it onto the stack.
I am pretty new to UITabBarController. I was trying to provide a navigation system in a viewController corresponding to a tab in tabViewController
created an instance of navigation controller in viewDidLOad
[testLabel setText:#"Test"];
self.navigator=[[UINavigationController alloc] initWithRootViewController:self];
[super viewDidLoad];
on button click I do this
NSLog(#"I am here");
StartWordPickerVC *aStartWordPickerVC=[[StartWordPickerVC alloc] initWithNibName:#"StartWordPickerVC" bundle:nil];
[self.navigator pushViewController:aStartWordPickerVC animated:YES];
[aStartWordPickerVC release];
But when I click button nothing happens
Can you please help me out in this
Thanks
Just add this in AppDelegate.h
UINavigationController *navigationController;
Just add this in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
}
I have a UITabBarController with 4 UINavigationControllers. I have implemented the didSelectViewController Delegate Method as follows:
-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
if ([viewController isKindOfClass:[UINavigationController class]]) {
[(UINavigationController *)viewController popToRootViewControllerAnimated:NO];
}
}
It crashes when a NavigationController is at a 2nd Level after didSelectRowAtIndexPath pushes a new viewController onto the stack.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
RootViewController *detailViewController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
// ...
detailViewController.title = [self.temp objectAtIndex:indexPath.row];
detailViewController.sort = self.title;
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
Of course the debugger with NSZombies enabled doesn't give any feedback.
However, if I add retain to detailViewController alloc;
RootViewController *detailViewController = [[[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil] retain];
It works, but leaks memory.
Any ideas what is wrong, how to fix, what is happening?
I have the similar scenario and i came up with following solution.
In my application i have login screen at launch and then I have UITabbarController with 4 UINavigationControllers.
I have created property of UINavigationController in AppDelegate.h file.
#property (strong, nonatomic) UINavigationController *navigationController;
Then
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions (NSDictionary *)launchOptions
{
//Override point for customization after application launch.
LoginViewController *loginViewController = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:loginViewController];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
Now when you need to pop to RootViewController then use following code
#import "AppDelegate.h"
[((AppDelegate *)[[UIApplication sharedApplication] delegate]).navigationController popToRootViewControllerAnimated:YES];
Hope this solves your problem.