I have a view controller say 'HomeViewController' on which I have added a UITabBarController, which has 4 UITabBarItems. Now what I want is, when I select the HomeViewController no tab should should be selected for the first time and another view should be loaded. I have tried UITabBar instead of UITabBarController but its not working. I have also tried :
tabBarController.selectedViewController=nil; //giving crash
tabBarController.selectedIndex=-1; //not working either
UITabBarItems should be selected when user will click on them.
You have to add UITabBar object on HomeViewController.
In ViewDidLoad you have to add following code:
ViewController1 *controller1 = [[ViewController1 alloc] initWithNibName:#"ViewController1" bundle:nil];
ViewController2 *controller2 = [[ViewController2 alloc] initWithNibName:#"ViewController2" bundle:nil];
viewControllersArray = [[NSArray alloc] initWithObjects:controller1,controller2, nil];
tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [[NSArray alloc] initWithArray:viewControllersArray];
for(int i = 0; i < tabBarController.tabBar.items.count; i++){
[[tabBarController.tabBar.items objectAtIndex:i] setTitle:[[tabBar.items objectAtIndex:i] title]];
}
isItemSelected = NO;
Also set the tag of tab bar items starting from 0. As 0 for first item, 1 for second item and so on.
and implement delegate method:
(void)tabBar:(UITabBar *)tabBar1 didSelectItem:(UITabBarItem *)item{
if(!isItemSelected){
isItemSelected = YES;
AppDelegate *appDel = (AppDelegate *)[UIApplication sharedApplication].delegate;
appDel.window.rootViewController = tabBarController;
}
tabBarController.selectedIndex = item.tag;
tabBarController.selectedViewController = [viewControllersArray objectAtIndex:item.tag];
}
I think this is not the right way, as Concept of creating TabBar says that " Show the particular controller of related tab". If u do not select any tab than what else you will show on screen, "A black screen ?". so please re-architecture your design.
Related
I try to push a UIViewController onto a UINavigationController. The NavigationBar changes (i.e. a back-button appears) but the view is not pushed (*).
I have a UITabBarController as my applications RootViewController.
When I switch to another tab and then switches back, the view (*) gets pushed.
I have never seen this behaviour before. My problem is exactly the same as this, however the methods that solved that issue did not solve mine.
Initially
After I press the row
I understand that this question might be related to issues in AppDelegate, therefore i post the code I use.
Code:
in AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[MagicalRecord setupCoreDataStackWithStoreNamed:#"DBModel"];
/* CONTACTS LIST CONTROLLER */
BoonContactListViewController *contactListViewController = [[BoonContactListViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *contactListNavigationController = [[UINavigationController alloc] initWithRootViewController:contactListViewController];
[contactListNavigationController setValue:[[BoonNavigationBar alloc]init] forKeyPath:#"navigationBar"];
contactListNavigationController.tabBarItem.title = [NSLocalizedString(#"CONTACTS", nil) capitalizedString];
contactListNavigationController.tabBarItem.image = [UIImage imageNamed:#"menu_contacts.png"];
/* INVITATIONS */
BoonInvitationListViewController *invitationListController = [[BoonInvitationListViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *invitationNavigationController = [[UINavigationController alloc] initWithRootViewController:invitationListController];
[invitationNavigationController setValue:[[BoonNavigationBar alloc]init] forKeyPath:#"navigationBar"];
invitationNavigationController.tabBarItem.title = [NSLocalizedString(#"SETTINGS", nil) capitalizedString];
invitationNavigationController.tabBarItem.image = [UIImage imageNamed:#"menu_invitations.png"];
/* SETTINGS */
BoonSettingsViewController *settingsViewController = [[BoonSettingsViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *settingsNavigationController = [[UINavigationController alloc] initWithRootViewController:settingsViewController];
[settingsNavigationController setValue:[[BoonNavigationBar alloc]init] forKeyPath:#"navigationBar"];
settingsNavigationController.tabBarItem.title = [NSLocalizedString(#"SETTINGS", nil) capitalizedString];
settingsNavigationController.tabBarItem.image = [UIImage imageNamed:#"menu_settings.png"];
/* TAB BAR */
BoonTabBarViewController *tabBarController = [[BoonTabBarViewController alloc] init];
tabBarController.viewControllers = #[contactListNavigationController, invitationNavigationController, settingsNavigationController];
[self.window setRootViewController:tabBarController];
[self.window makeKeyAndVisible];
[tabBarController showLogin];
return YES;
}
EDIT:
In the viewController that i am trying to push, neither viewWillAppear, viewDidLoad nor viewDidAppear is called.
If I use presentViewController: animated: completion: I get the preferred behaviour, id rather not though
EDIT 2
How I push my new VC
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
BoonContactInfoViewController *contactInfoViewController = [[BoonContactInfoViewController alloc] initWithNibName:nil bundle:nil];
NSLog(#"NAV %#", self.navigationController);
[self.navigationController pushViewController:contactInfoViewController animated:YES];
}
EDIT 3
It is only the initial tab that cannot push ... if i swap places of the first and second tab, i can push a view controller using in the way i do above.
EDIT 4
It works if i (in my tabBarController) calls
self.selectedIndex = 1;
self.selectedIndex = 0;
EDIT 5
- (void)showLogin
{
if([BoonUserHandler getLogin].length > 0 && [BoonUserHandler getPassword].length > 0){
return;
}
BoonWelcomeViewController *welcomeWC = [[BoonWelcomeViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *welcomeNavigationController = [[UINavigationController alloc] initWithRootViewController:welcomeWC];
[welcomeNavigationController setNavigationBarHidden:YES];
[self presentViewController:welcomeNavigationController animated:NO completion:nil];
}
What version of iOS are you developing for?
I'd first ask why you're hacking in a nav bar using:
[settingsNavigationController setValue:[[BoonNavigationBar alloc]init] forKeyPath:#"navigationBar"];
rather than the iOS5+ UINavigationController method:
- (instancetype)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass
But my overall suggestion would be to remove all this code and use a storyboard. This looks like the perfect opportunity.
I think you are getting wrong Navigation controller to push that's why it showing this problem..
You have to fetch right navigation controller from tab controller
self.tabBarController.selectedIndex = 0;
just change tab controller selected index
I have an app with an "old" Tabbarcontroller and a MainWindow.xib. I have to delete the tabbarcontroller logic to transform the app and made a "Left side menu" type, like facebook. I have a problem, i have alredy created the left side menĂ¹ with a tableviewcontroller and i can open,close and push correctly my controllers... Now i want to insert a different customnavigation bar class each navigation controller (in the old version of the app each navigation controller had his custom navigation class to change che image in relation with the active viewcontroller). This is the code i use in the tableview didselect method of a row in my left side menu:
if (indexPath.row==1) {
DemoViewController *demoController = [[DemoViewController alloc] init];
UINavigationController *navigationController = self.menuContainerViewController.centerViewController;
[navigationController setValue:[[CustomNavigationBar alloc]init] forKeyPath:#"navigationBar"];
NSArray *controllers = [NSArray arrayWithObject:demoController];
navigationController.viewControllers = controllers;
[self.menuContainerViewController setMenuState:MFSideMenuStateClosed];
}
this code manage correctly the slide and load correctly the viewcontroller inside MFSideMenu. The custom navigationbar class is assigned but not works correctly:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
this method is never called, maybe MFSideMenu overwrites the uinavigationcontroller delegate? How i can do to made "active" again this navigation controller delegate method?
found a solution,this code:
DemoViewController *demoController = [[DemoViewController alloc] init];
UINavigationController *navigationController = self.menuContainerViewController.centerViewController;
CustomNavigationBar *navClass=[[CustomNavigationBar alloc]init];
[navigationController setValue:navClass forKeyPath:#"navigationBar"];
[navigationController setDelegate:navClass];
NSArray *controllers = [NSArray arrayWithObject:demoController];
navigationController.viewControllers = controllers;
[self.menuContainerViewController setMenuState:MFSideMenuStateClosed];
instead of:
DemoViewController *demoController = [[DemoViewController alloc] init];
UINavigationController *navigationController = self.menuContainerViewController.centerViewController;
[navigationController setValue:[[CustomNavigationBar alloc]init] forKeyPath:#"navigationBar"];
NSArray *controllers = [NSArray arrayWithObject:demoController];
navigationController.viewControllers = controllers;
[self.menuContainerViewController setMenuState:MFSideMenuStateClosed];
In this way the delegate is assigned correctly...
I want to create UISplitView programmatically after pressing a button in a view. For UISplitView, I have two view controllers called as MyTableViewController and MyDetailViewController. This is what I am doing in the action of the button:
UISplitViewController* splitVC = [[UISplitViewController alloc] init];
MyTableViewController* firstVC = [[MyTableViewController alloc] init];
MyDetailViewController* secondVC = [[MyDetailViewController alloc] init];
UINavigationController *leftNavController = [[UINavigationController alloc] init];
[leftNavController pushViewController:firstVC animated:NO];
splitVC.viewControllers = [NSArray arrayWithObjects:leftNavController, secondVC, nil];
AppDelegate * appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.window setRootViewController:splitVC];
But secondVC (the detail view) doesn't show up. It is just black. Though, the firstVC (the table view) shows up as it should be. What could be the reason?
You should take a look at using [self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewIdentifier"], and set an identifier for the view controller in your storyboard. Calling init on a view controller doesn't reference the storyboard you have created, so you need to instead pull the view controller out of the storyboard. The table view worked because its layout is programmed into the UITableViewController class.
My IOS app has a login sequence that cannot be modified, once the sequence is complete I do the following in the app delegate
- (UIViewController*)newRootViewController {
NViewController *nView = [[NViewController alloc]
initWithNibName:#"NViewController"
bundle:nil];
UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController:nView];
[nView release];
return navVC;
}
Once in nView is it possible to add a tab bar controller or how can I replace nView with a tab bar controller.
You can create a UITabBarController then add your NViewController and other controllers to the tab bar.
NViewController *nView = [[NViewController alloc]
initWithNibName:#"NViewController"
bundle:nil];
//Create my tab bar
UITabBarController* myTabController = [[UITabBarController alloc]init];
//Add my tabs
NSArray* tabs = [[NSArray alloc]initWithObjects:nView, nil];
[myTabController setViewControllers:tabs];
Can I change the first screen of a tab item programatically?
For example,
When user is in Tab A, upon tapping a button there, user will be
navigated to Tab C with Screen 1 However, when user is in Tab C, upon
tapping a button here, user will be navigated to Tab C with Screen 2.
Therefore, both screen 1 and 2 will be the first screen of Tab C
depend on where the user comes from.
Can I achieve something like that?
Thanks!
Based on this post How to replace a navigation root controller by tab bar controller in existing iphone app , can change the view controllers by this code:
NSMutableArray * viewControllers = [[NSMutableArray alloc]init];
FirstViewController * firstViewController = [[FirstViewController alloc]initWithNibName:#"FirstViewController" bundle:nil];
UINavigationController * nvc = [[UINavigationController alloc] initWithRootViewController:firstViewController];
[firstViewController release];
[viewControllers addObject:nvc];
[nvc release];
SecondViewController * secondViewController = [[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
nvc = [[UINavigationController alloc] initWithRootViewController:secondViewController];
[secondViewController release];
[viewControllers addObject:nvc];
[nvc release];
UITabBarController * tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = viewControllers;
[window addSubview:tabBarController.view];