I am using iOS 6 Preservation and Restoration (without Storyboard), it is working fine with navigation controller , but if i manually add Tabbar controller on main window , i am not getting selected tab.
eg.
ListViewController *list = [[ListViewController alloc] initWithNibName:#"ListViewController" bundle:nil];
SettingViewController *setting = [[SettingViewController alloc] initWithNibName:#"SettingViewController" bundle:nil];
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:list];
navigation.restorationIdentifier = #"NavigationControllerID";
self.tabbar = [[UITabBarController alloc] init];
self.tabbar.restorationIdentifier = #"TabbarControllerID";
self.tabbar.viewControllers = #[navigation,setting];
[[_tabbar.tabBar.items objectAtIndex:0] setTitle:NSLocalizedString(#"List", #"comment")];
[[_tabbar.tabBar.items objectAtIndex:1] setTitle:NSLocalizedString(#"Setting", #"comment")];
self.window.rootViewController = self.tabbar;
[self.window makeKeyAndVisible];
in t his case i am getting first tab selected every time.i have implatementd
+ (UIViewController *)viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder
for setting view controller.
By Adding this methods in Appdelegate
NSString * const AppDelegateRootVCKey = #"AppDelegateRootVCKey";
- (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder {
//Adding last tabbar selected index
[coder encodeObject:[NSString stringWithFormat:#"%d",self.tabbar.selectedIndex]forKey:AppDelegateRootVCKey];
}
- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder {
//Setting Last tabbar selected index
NSString *selectedStr = [coder decodeObjectForKey:AppDelegateRootVCKey];
self.tabbar.selectedIndex = [selectedStr intValue];
return YES;
}
Related
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;
}
I have created uitabbarview controller using the below code
In the uitabbar controller i want to display tile for every view
Please let me know how to add title for each view ( tab bar item )
myTabBarController = [[UITabBarController alloc] init];
MyDialerViewController *aDialerViewController = [[MyDialerViewController alloc]init];
MyCallLogViewController *aCallLogViewController = [[MyCallLogViewController alloc] init];
TemplateViewController *aTemplateViewController = [[TemplateViewController alloc] init];
NSArray* controllers = [NSArray arrayWithObjects:aDialerViewController, aCallLogViewController, aTemplateViewController, nil];
myTabBarController.viewControllers = controllers;
myTabBarController.delegate = self;
myTabBarController.selectedIndex = 0;
[controllers release];
[aDialerViewController release];
[aCallLogViewController release];
[aTemplateViewController release];
[self.window addSubview:myTabBarController.view];
[self.window makeKeyAndVisible];
I set the title of the navcontroller directly in the appDelegate.
aDialerViewController.title = NSLocalizedString(#"Dialer Title", #"Dialer Title");
aCallLogViewController.title = #"Title";
aTemplateViewController.title = #"Title";
I'd also set it in the viewDidLoad method of those viewControllers.
Works fine for me. Remember to localize, just incase you need it in the future. (if not intended to, you should look into it)
self.viewcontroller.tabBarItem = // a UITabBarItem instance
Make an instance of UITabBarItem
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UITabBarItem_Class/Reference/Reference.html#//apple_ref/doc/c_ref/UITabBarItem
(id)initWithTitle:(NSString *)title image:(UIImage *)image tag:(NSInteger)tag
You could write that in the initializer function of each viewcontroller.
I would like to present a view controller modally before calling -makeKeyAndVisible on the application's window. However, this code only shows the mainNav view controller:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
MainViewController *main = [[MainViewController alloc] init];
UINavigationController *mainNav = [[UINavigationController alloc] initWithRootViewController:main];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"Restore"])
{
DetailViewController *detail = [[DetailViewController alloc] init];
UINavigationController *detailNav = [[UINavigationController alloc] initWithRootViewController:detail];
// changing main to mainNav does not help
[main presentModalViewController:learnNav animated:NO];
[detailNav release]; [detail release];
}
self.window.rootViewController = mainNav;
[main release]; [mainNav release];
[self.window makeKeyAndVisible];
return YES;
}
What am I missing?
You should better make the window appear and then present the modal view with animated=NO. What's the point of presenting the modal view before everything else is instantiated and displayed?
Edit
To try to make your code work, here are a couple of hints. Try this:
[mainNav presentModalViewController:learnNav animated:NO];
or this:
[main.navigationController presentModalViewController:learnNav animated:NO];
I'd say that these two methods work best if they're put after the makeKeyAndVisible call.
i have an app with tab bar and a navigation controller inside every tab.
i have set a notification that when it lunches the user can get lunch the app by pressing the action on the alert.
i want to redirect the user to one of the views inside one of the controllers.
i have tried this:
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
NSArray *data = [notif.userInfo objectForKey:#"todoDate"];
NSInteger ind = [[data objectAtIndex:2] integerValue];
QuickViewController *detailViewController ;
detailViewController = [[QuickViewController alloc] initWithNibName:#"QuickViewController" bundle:nil];
detailViewController.title = #"Edit";
detailViewController.personName = [data objectAtIndex:0];
detailViewController.DelitionDate=[data objectAtIndex:1];
detailViewController.personCategory=#"NO Category";
detailViewController.personID = ind r ;
rootControler.selectedIndex = 1;
[rootControler.tabBarController.selectedViewController.navigationController pushViewController:detailViewController animated:YES];
}
but nothing is happening (no crashing) except of the :rootControler.selectedIndex = 1;
when i tried :
presentModalViewController
i got the view perfectly but without the navigation controller.
thanks
shani
It sounds like you're pushing detailViewController when you really want to push a UINavigationController with detailViewController as its root view. Try something like this:
QuickViewController *detailViewController ;
detailViewController =
[[QuickViewController alloc] initWithNibName:#"QuickViewController"
bundle:nil];
UINavigationController *navigationController =
[[UINavigationController alloc] initWithRootViewController:detailViewController];
[detailViewController release];
...
[rootControler.tabBarController.selectedViewController.navigationController
pushViewController:navigationController animated:YES]
I've programmatically created a UITabBarController that is loaded in my App Delegate like this:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
tabBarController = [[UITabBarController alloc] init];
myTableViewController = [[MyTableViewController alloc] init];
UINavigationController *tableNavController = [[[UINavigationController alloc] initWithRootViewController:myTableViewController] autorelease];
myTableViewController.title = #"Tab 1";
[myTableViewController release];
mySecondTableViewController = [[MySecondTableViewController alloc] init];
UINavigationController *table2NavController = [[[UINavigationController alloc] initWithRootViewController:mySecondTableViewController] autorelease];
mySecondTableViewController.title = #"Tab 2";
[mySecondTableViewController release];
tabBarController.viewControllers = [NSArray arrayWithObjects:tableNavController, table2NavController, nil];
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
}
Now the issue I have is that I can get into the views no problem, but when I try and click onto any item in the Table View, I can't get a secondary table view to appear in any tab. The tabs work absolutely fine, just the secondary views. I'm using the code below in my myTableViewController to run when selecting a specific row (the code reaches the HELP line, and crashes)...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
// this gets the correct view controller from a list of controllers
SecondaryViewController *svc = [self.controllers objectAtIndex:row];
/*** HELP NEEDED WITH THIS LINE ***/
[self.navigationController pushViewController:svc animated:YES];
}
Simply put, I'm trying to switch views to the new view controller whilst keeping the tabs available and using the navigation to go back and forth (like in the iTunes App).
Simply put, I was creating the controller array, self.controllers, and adding objects, and then releasing the objects.
If you do not release the object until the array is released, it appears to work no problem.
You've not included in your question how you initialize the self.controllers array.
I suspect this array is not filled with initialized SecondaryViewController objects.
EDIT (Added Code example that works for me):
the .h file:
#interface FirstLevelViewController : UITableViewController {
NSArray *controllers;
}
#property (nonatomic, retain) NSArray *controllers;
#end
and the .m file:
#implementation FirstLevelViewController
#synthesize controllers;
- (void)viewDidLoad {
self.title = #"First Level";
NSMutableArray *array = [[NSMutableArray alloc] init];
// Disclosure Button
DisclosureButtonController *disclosureButtonController =
[[DisclosureButtonController alloc]
initWithStyle:UITableViewStylePlain];
disclosureButtonController.title = #"Disclosure Buttons";
disclosureButtonController.rowImage = [UIImage
imageNamed:#"disclosureButtonControllerIcon.png"];
[array addObject:disclosureButtonController];
[disclosureButtonController release];
// deleted further adds to array ...
self.controllers = array;
[array release];
[super viewDidLoad];
}