Can't get tabbar app to popToRootViewController - iphone

I have a programatic tabbar delagate with navbar with a banner view delegate. And for the life of me I can't seem to get the tabs to pop the root view on click. I know I need to use something like [self.navigationController popToRootViewControllerAnimated:NO]; But I don't know where to put it in my app delegate.
#implementation AppDelegate {
UITabBarController *_tabBarController;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
NSError *setCategoryError = nil;
CGRect bounds = [[UIScreen mainScreen] bounds];
self.window = [[UIWindow alloc] initWithFrame:bounds];
self.window.backgroundColor = [UIColor whiteColor];
NSMutableArray * viewControllers = [[NSMutableArray alloc] init];
NSString * subscriptionListFile = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:#"Subscription.plist"];
NSDictionary * subscriptionList = [[NSDictionary alloc] initWithContentsOfFile:subscriptionListFile];
NSArray * subscriptionFolders = subscriptionList[#"Folders"];
NewsListViewController * newsController = nil;
UINavigationController * newsNavigationController = nil;
BannerViewController * bannervcs = nil;
for (NSDictionary * folderDetails in subscriptionFolders) {
NSArray * newsItems = folderDetails[#"Items"];
NSString * folderTitle = folderDetails[#"FolderName"];
NSString * folderIcon = folderDetails[#"FolderIcon"];
UIImage * folderIconImage = [UIImage imageNamed:folderIcon];
newsController = [[NewsListViewController alloc] initWithNewsSourceList:newsItems];
[newsController setTitle:folderTitle];
newsNavigationController = [[UINavigationController alloc] initWithRootViewController:newsController];
[newsNavigationController setTitle:folderTitle];
bannervcs = [[BannerViewController alloc] initWithContentViewController:newsNavigationController];
[bannervcs.tabBarItem setImage:folderIconImage];
[viewControllers addObject:bannervcs];
}
_tabBarController = [[UITabBarController alloc] init];
_tabBarController.viewControllers = viewControllers;
self.window.rootViewController = _tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
#end
Any idea where I add popToRootViewController? I tried at the end but it doesnt seem to be grabbing any controller...

You'll need to set something to be your UITabBarControllerDelegate. Assuming you want to try this out on your AppDelegate, add the line to your method:
_tabBarConroller.delegate = self;
And then, add this method to your AppDelegate (since it is now also considered an UITabBarControllerDelegate)
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
viewController.navigationController popToRootViewControllerAnimated:NO];
}
This is assuming that, regardless of what state the user left the navigation stack on a tab, that tapping another tab always takes the user to the root view controller of the nav stack.

If you want navigationController in your tabBar then you have to add yourNavigationController instead of viewController.
So in your case you are not adding navigationControllers to your tabBarControllers array.
[viewControllers addObject:bannervcs];
so instead of adding bannervcs add newsNavigationController
[viewControllers addObject:newsNavigationController];
For more info just read and take sample code from UITabBarController Class Reference

Related

SplitView navigation issue in ipad

i implemented a split view in my app. When my app launch it shows fine.
masterview=Leftside view & detailView = Home view
But my master view also contains 2 Table view. when i clicked the any row of table view, the detail view(Now, class view) is not get display.
Mean i want to disply display mutiple detail view as per master view's table row selected.
my code for split view is as follow:
// AppDelegate.h
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
LeftViewController *masterViewController = [[LeftViewController alloc] initWithNibName:#"LeftViewController_iPad" bundle:nil] ;
UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController] ;
HomeViewController *detailViewController = [[HomeViewController alloc] initWithNibName:#"HomeViewController_iPad" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
masterViewController.home_Detail = detailViewController;
self.splitViewController = [[UISplitViewController alloc] init] ;
self.splitViewController.delegate = detailViewController;
self.splitViewController.viewControllers=[NSArray arrayWithObjects:masterNavigationController,detailNavigationController, nil];
self.window.rootViewController = self.splitViewController;
[self.window makeKeyAndVisible];
}
//LeftView.m
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.appDelegate.splitViewController viewWillDisappear:YES];
NSMutableArray *viewControllerArray=[[NSMutableArray alloc] initWithArray:[[self.appDelegate.splitViewController.viewControllers objectAtIndex:1] viewControllers]];
[viewControllerArray removeAllObjects];
if (tableView==tbl_class)
{
self.class_VC=[[Class_Vice_ViewController alloc]initWithNibName:#"Class_Vice_ViewController" bundle:nil];
[[NSUserDefaults standardUserDefaults]setInteger:[[[classNames objectAtIndex:indexPath.row]valueForKey:#"class_id"]intValue] forKey:#"psel_class"];
NSLog(#"%d",[[[classNames objectAtIndex:indexPath.row]valueForKey:#"class_id"]intValue]);
[viewControllerArray addObject:self.class_VC];
self.appDelegate.splitViewController.delegate = self.class_VC;
[[self.appDelegate.splitViewController.viewControllers objectAtIndex:1] setViewControllers:viewControllerArray animated:NO];
[class_VC viewWillAppear:YES];
}
}
Help me to Solve this issue
The offending line is this one in the didSelectRowAtIndexPath: method:
[self.appDelegate.splitViewController viewWillDisappear:YES];
I don't know why you put that in, but if you remove it, it should work. You also don't need this line:
[self.class_VC viewWillAppear:YES];
While it is quite common to override viewWillAppear: and viewWillDisappear:, you almost never call them like you're doing.

change a view controller of UITabBarController

In a UITabBarController, upon selecting a tab, I want that tab's UIViewController to change (assign a new viewcontroller). I'm trying this-
NSMutableArray *tabBarViewControllers = [myUITabBarController.viewControllers mutableCopy];
[tabbarViewControllers replaceObjectAtIndex:0 withObject:[[myViewcontroller1 alloc] init]];
[myUITabBarController setViewControllers:tabbarViewControllers];
But it gives error. How to assign a new UIViewController and refresh instantly?
This is based on femina's answer but doesn't require you to build the whole array of view controllers, it just lets you replace an existing view controller with another. In my case I wanted to swap in a different xib file for the iPhone 5 screen:
if ([[UIScreen mainScreen] bounds].size.height == 568) {
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:self.tabBarController.viewControllers];
Tracking *tracking568h = [[Tracking alloc] initWithNibName:#"Tracking-568h" bundle:nil];
tracking568h.title = [[viewControllers objectAtIndex:0] title];
tracking568h.tabBarItem = [[viewControllers objectAtIndex:0] tabBarItem];
[viewControllers replaceObjectAtIndex:0 withObject:tracking568h];
[tracking568h release];
[self.tabBarController setViewControllers:viewControllers animated:FALSE];
}
This changes the view controller for the first tab, keeping the same tab icon and label.
Please see this code , it offers 2 tabbar's with navigation.
In the AppDelegate.h please declare
UINavigationController *nav1;
UINavigationController *nav2;
UITabBarController *tab;
And in the Appdelegate.m , in the didFinishLaunchingWithOptions please add:-
tab = [[UITabBarController alloc]init];
ViewController *view1 = [[ViewController alloc]init];
nav1= [[UINavigationController alloc]initWithRootViewController:view1];
UITabBarItem *tab1 = [[UITabBarItem alloc]initWithTitle:#"Add" image:[UIImage imageNamed:#"Plus.png"] tag:1];
view1.title = #"Add";
[view1 setTabBarItem:tab1];
SettingsViewController *view2 = [[SettingsViewController alloc]init];
nav2= [[UINavigationController alloc]initWithRootViewController:view2];
UITabBarItem *tab2 = [[UITabBarItem alloc]initWithTitle:#"Setting" image:[UIImage imageNamed:#"settings.png"] tag:2];
view2.title = #"Setting";
[view2 setTabBarItem:tab2];
tab.viewControllers = [NSArray arrayWithObjects:nav1,nav2,nil];
self.window.backgroundColor = [UIColor whiteColor];
self.window.rootViewController = tab;
Also check this link for further implementation ... Hope this helps :)
UItabBar changing View Controllers
In the AppDelegate.h
UIViewController *vc1;
UIViewController *vc2;
UIViewController *vc3;
in the Appdelegate.m
in the didFinishLaunchingWithOptions
NSMutableArray *listOfViewControllers = [[NSMutableArray alloc] init];
vc1 = [[UIViewController alloc] init];
vc1.title = #"A";
[listOfViewControllers addObject:vc1];
vc2 = [[UIViewController alloc] init];
vc2.title = #"B";
[listOfViewControllers addObject:vc2];
vc3 = [[UIViewController alloc] init];
vc3.title = #"C";
[listOfViewControllers addObject:vc3];
[self.tabBarController setViewControllers:listOfViewControllers
animated:YES];

make UITabBar without adding in appDelegate file

I am making an application which will have 3 pages
Login Page - first page after the app loads
My First Page- when user successfully logs in then he comes into this page.This page
contains a UITabBar with two UITabBarItems. The first one is connected to
My firstPage
and the other one to My Second Page.
My Second Page - this is another UIViewController.
I have made the login page but I am unable to find the solution to UITabBar adding in My First Page
Please help me out
Define
AppDelegate.h
#property (strong, nonatomic) UITabBarController *tabBarController;
in AppDelegate.m
didFinishLaunchingWithOptions
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.delegate=self;
self.tabBarController.selectedIndex=0;
self.tabBarController.delegate=self;
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
return YES;
}
now when you get success login write below code in that method
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
delegate.tabBarController = [[UITabBarController alloc] init];
delegate.tabBarController.selectedIndex = 0;
delegate.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, nil];
delegate.tabBarController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self.navigationController pushViewController:delegate.tabBarController animated:YES];
Try this out,
suppose this is LoginViewController.m
-(IBAction)loginButtonClicked:(id)sender
{
[self createTabBarView];
}
//Create TabBar View here
-(void)createTabBarView
{
NSMutableArray *tabItems = [NSMutableArray array];
UIViewController *firstViewController = [[FirstViewController alloc] init];;
firstViewController = #"First View";
firstViewController = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemContacts tag:0];
[tabItems addObject:firstViewController];
UIViewController *secondViewController = [[SecondViewController alloc] init];;
secondViewController = #"Second View";
secondViewController = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemContacts tag:1];
[tabItems addObject:secondViewController];
self.tabBarController = [[UITabBarController alloc]init];
self.tabBarController.viewControllers = tabItems;
self.tabBarController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:tabBarController animated:YES];
}
Thanks,
Nikhil.
Are you using interface builder?
From my point of view, I'd rather like to use programmatic way to implement it.
//In the appDidFinishLaunch method
BOOL loggedIn = [[NSUserDefault standDefault]boolForKey:"userlogin"];
if(loggedIn)
{
//Setup your UITabbarViewController
}
else
{
//Setup your loginView Controller
}
After login in LogInViewController
- (void)didLogin
{
YourAppDelegate *delegate = [UIApplication shareApplication].delegate;
[delegate.window addSubView:self.tabBarViewController.view];
[delegate.window removeSubView:self.view]
//Other Config
}
You should create Tabbar at place where you can identify that login is successfully done. This method should be part of your loginViewController.
Create a function like below to create a Tabbar and present it over loginController.
-(void) createTabBarController
{
UITabBarController *tabBar = [[UITabBarController alloc]init];
UIViewController *firstViewController = [[[UIViewController alloc] init]autorelease];
UINavigationController *firstNavController = [[UINavigationController alloc]initWithRootViewController:firstViewController];
firstNavController.tabBarItem.title=#"First Controller";
firstNavController.tabBarItem.image = [UIImage imageNamed:#"first.png"];
UIViewController *secondViewController = [[[UIViewController alloc] init]autorelease];
UINavigationController *secondNavController = [[UINavigationController alloc]initWithRootViewController:secondViewController];
secondNavController.tabBarItem.title=#"First Controller";
secondNavController.tabBarItem.image = [UIImage imageNamed:#"first.png"];
[tabBar setViewControllers:[NSArray arrayWithObject:firstNavController,secondNavController,nil]];
[firstNavController release];
[secondNavController release];
[self presentModalViewController: tabBar];
[tabBar release];
}

iPhone/Objective-c - Gaining access to a previous ViewController from a subview?

How do I access a previous view controller while in a subview? Because I'm able to perform actions but I'm just not able to use self.[my main view controller].
This is my code, for testing purposes:
PhotoViewController.m
-(IBAction)likeButton:(UIButton *)sender
{
//this part works
NSString *num = #"2";
self.label.text = [NSString stringWithFormat:#"%# + %#",
self.label.text,
num];
//this part doesn't work
//switch over to the third view to see if it worked
self.tabBarController.selectedIndex = 0;
}
I have a UITabBarController and one of its view controllers has a UIScrollView. Inside of the UIScrollView is a PhotoViewController object.
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch
MyTabBarViewController *vc2 = [[MyTabBarViewController alloc] init];
SecondViewController *vc3 = [[SecondViewController alloc] init];
controller = [[DemoAppViewController alloc] init];
controller.view.frame = CGRectMake(0, 20, 320, 460);
controller.title = #"Intro Screen";
vc2.title = #"Explore";
vc3.title = #"Send a Pic";
UITabBarController *tbc = [[UITabBarController alloc] init];
tbc.viewControllers = [NSArray arrayWithObjects:controller, vc2, vc3, nil];
[controller release];
[vc2 release];
[vc3 release];
[self.window addSubview:tbc.view];
[self.window makeKeyAndVisible];
return YES;
}
Also, my TabBarViewController.m //not my actual UITabBarController though, wording is confusing
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
arrayCount = [array count];
scroller.delegate=self;
scroller.pagingEnabled=YES;
scroller.directionalLockEnabled=YES;
scroller.showsHorizontalScrollIndicator=NO;
scroller.showsVerticalScrollIndicator=NO;
//should have an array of photo objects and the number of objects, correct?
scrollWidth = 0;
scroller.contentSize=CGSizeMake(arrayCount*scroller.frame.size.width, scroller.frame.size.height);
for (int i = 0; i < arrayCount;i++) {
PhotoViewController *pvc = [[PhotoViewController alloc] initWithNibName:#"PhotoViewController" bundle:nil];
UIImageView *scrollImageView = [[UIImageView alloc] initWithFrame:CGRectOffset(scroller.bounds, scrollWidth, 0)];
CGRect rect = scrollImageView.frame;
pvc.view.frame = rect;
pvc.label.textColor = [UIColor whiteColor];
id individualPhoto = [array objectAtIndex:i];
NSLog(#"%#",individualPhoto);
NSArray *keys=[individualPhoto allKeys];
NSLog(#"%#",keys);
NSString *imageURL=[individualPhoto objectForKey:#"source"];
NSURL *url = [NSURL URLWithString:imageURL];
NSData *data = [NSData dataWithContentsOfURL:url];
pvc.imageView.image = [[UIImage alloc] initWithData:data];
pvc.label.text = [individualPhoto objectForKey:#"id"];
[scroller addSubview:pvc.view];
[scrollImageView release];
//[pvc release];
scrollWidth += scroller.frame.size.width;
}
if (arrayCount > 3) {
pageControl.numberOfPages=3;
} else {
pageControl.numberOfPages=arrayCount;
}
pageControl.currentPage=0;
}
If a UIView subclass needs to message a controller above itself, a common (and often recommended?) way to do this is to have the view subclass implement the delegate protocol (a weak linked instance variable pointing to the view controller that you want to use). The view controller should then set itself as the delegate of the view when that view is being initialize.
Try defining this method in your PhotoViewController:
+ (YOURTABBARCONTROLLER*)parentTabBarController:(UIResponder*)view {
id nextResponder = nil;
id v = view;
while (nextResponder = [v nextResponder]) {
NSLog(#"Found Responder: %#", nextResponder); //-- ADDED THIS
if ([nextResponder isKindOfClass:[YOURTABBARCONTROLLER class]])
return nextResponder;
v = nextResponder;
}
return nil;
}
it will traverse the responder chain and return the first controller of a given type that is found. Replace YOURTABBARCONTROLLER with your actual tab bar controller class and you should be able to have:
-(IBAction)likeButton:(UIButton *)sender
{
//this part works
NSString *num = #"2";
self.label.text = [NSString stringWithFormat:#"%# + %#",
self.label.text,
num];
[PhotoViewController parentTabBarController:self.view].selectedIndex = 0;
// self.tabBarController.selectedIndex = 0;
}
Updated
-(IBAction)likeCommentButton:(UIButton *)sender
{
//code goes here
TypeSomethingViewController *typeSomethingViewController = [[TypeSomethingViewController alloc] init];
typeSomethingViewController.delegate = self;
[self presentModalViewController:typeSomethingViewController animated:YES];
[typeSomethingViewController release];
}
-(void)typeSomethingViewController:(TypeSomethingViewController *)controller didTypeSomething:(NSString *)text
{
//NSLog(#"response: %#", controller);
NSString *commentID = self.label.text;
for(UIViewController *controller in [PhotoViewController parentTabBarController:self.parentViewController.view].viewControllers)
{
if([controller isKindOfClass:[DemoAppViewController class]])
{
DemoAppViewController *davc = (DemoAppViewController *)controller;
//[davc commentPicture:commentID :message];
[davc likePicture:commentID];
}
}
[PhotoViewController parentTabBarController:self.view].selectedIndex = 0;
[self dismissModalViewControllerAnimated:YES];
}
Try this out to switch to the first controller.
self.tabBarController.selectedViewController
= [self.tabBarController.viewControllers objectAtIndex:0];
Change the index value to switch to whichever controller you want to switch to.
The tabBarController should be a property of the app delegate.
Try accessing it with :
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication]
delegate];
appDelegate.tabBarController.selectedIndex = 0;
Unless you declare the same property in PhotoViewController, you won't be able to access it this way.
Try importing the app delegate header in PhotoViewController.h like so :
#import "MyAppDelegate"
then try this code above replacing tabBarController by tbc which, as the example suggests is the name given to this property.

ViewDid appear not working xcode

Hai,
I have created a tab based iRestaura project. I use 5 tab bar items. One of the tabbar name is Customer. When I tap on customer another tabbar is created with 3 viewcontroller programmatically. When I use view didload method tabbarcontroller is created successfully. But when i use view didAppear then tabbar controller is not created tabbar. In both of cases the other three viewcontroller which is created programmatically , there is not view did appear is not working. But all of case I need to use viewDidAppear method .
Plz anyone can help me...
The viewDidAppear method which not working is given bellow .....
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UITabBarController *tabBarController1=[[UITabBarController alloc] init];
CustomerListViewController *customerListViewController=[[CustomerListViewController alloc] init];
customerListViewController.title=#"Customer List";
UIImage *anImage1 = [UIImage imageNamed:#"customer.png"];
UITabBarItem *theItem1 = [[UITabBarItem alloc] initWithTitle:#"CustomerList" image:anImage1 tag:0];
customerListViewController.tabBarItem = theItem1;
SelectedCustomerViewController *selectedCustomerViewController= [[SelectedCustomerViewController alloc] init];
selectedCustomerViewController.title=#"Selected Customer";
UIImage *anImage3 = [UIImage imageNamed:#"selectedCustomer.png"];
UITabBarItem *theItem = [[UITabBarItem alloc] initWithTitle:#"Selected Customer" image:anImage3 tag:1];
selectedCustomerViewController.tabBarItem = theItem;
InvoiceListViewController *invoiceListViewController=[[InvoiceListViewController alloc] init];
invoiceListViewController.title=#"Invoice List";
UIImage *anImage2 = [UIImage imageNamed:#"invoiceNo.png"];
UITabBarItem *theItem2 = [[UITabBarItem alloc] initWithTitle:#"Invoice List" image:anImage2 tag:2];
invoiceListViewController.tabBarItem = theItem2;
NSMutableArray *controllers=[[NSMutableArray alloc] init];
[controllers addObject:customerListViewController];
// [controllers1 addObject:vc1];
[controllers addObject:selectedCustomerViewController];
[controllers addObject:invoiceListViewController];
///[controllers1 addObject:vc4];
tabBarController1.viewControllers=controllers;
[self.navigationController setNavigationBarHidden:YES animated:YES];
[[self view] addSubview:tabBarController1.view];
for (int t=0; t<[controllers count]; t++)
{
NSLog(#"controller%#",[controllers objectAtIndex:t]);
}
}
Try this:
Firstly use the below function on your Tabbar controller .m file:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[viewController viewWillAppear:YES];
}
And in your "viewDidLoad" function of Tabbar controller .m file, use "localNavigationController.delegate = self;" as used in given example below.
UserListing *nearBy = [[UserListing alloc] init];
nearBy.tabBarItem.image = [UIImage imageNamed:#"icoTabNearby.png"];
nearBy.tabBarItem.title = #"Nearby";
localNavigationController = [[UINavigationController alloc] initWithRootViewController:nearBy];
localNavigationController.delegate = self;
Hope it works for you.