iPhone : Display popOver from tabBarItem - iphone

I wonder how I can display a popOver from a tabBarItem ?
Here is how I manage my tabBarController :
tabBarController = [[UITabBarController alloc] init];
searchSplitViewController = [[UISplitViewController alloc] init];
searchRoot = [[[EI_iPad_Home_Root_ViewController alloc] init] autorelease];
searchDetail = [[[EI_iPad_Home_Detail_ViewController alloc] init] autorelease];
searchRootNav = [[[EI_Navigation_ViewController alloc] initWithRootViewController:searchRoot]autorelease];
searchDetailNav = [[[EI_Navigation_ViewController alloc] initWithRootViewController:searchDetail] autorelease];
searchSplitViewController.viewControllers = [NSArray arrayWithObjects:searchRootNav, searchDetailNav, nil];
searchSplitViewController.delegate = searchDetail;
favoritesSplitViewController = [[UISplitViewController alloc] init];
favoritesRoot = [[[EI_iPad_Favorites_Root_ViewController alloc] init] autorelease];
favoritesDetail = [[[EI_iPad_Favorites_GeneralDetail_ViewController alloc] init] autorelease];
favoritesRootNav = [[[EI_Navigation_ViewController alloc] initWithRootViewController:favoritesRoot]autorelease];
favoritesDetailNav = [[[EI_Navigation_ViewController alloc] initWithRootViewController:favoritesDetail] autorelease];
favoritesSplitViewController.viewControllers = [NSArray arrayWithObjects:favoritesRootNav, favoritesDetailNav, nil];
favoritesSplitViewController.delegate = favoritesDetail;
agencySplitViewController = [[UISplitViewController alloc] init];
agencyRoot = [[[EI_iPad_Agency_Root_ViewController alloc] init] autorelease];
agencyDetail = [[[EI_iPad_Agency_GeneralDetail_ViewController alloc] init] autorelease];
agencyRootNav = [[[EI_Navigation_ViewController alloc] initWithRootViewController:agencyRoot]autorelease];
agencyDetailNav = [[[EI_Navigation_ViewController alloc] initWithRootViewController:agencyDetail] autorelease];
agencySplitViewController.viewControllers = [NSArray arrayWithObjects:agencyRootNav, agencyDetailNav, nil];
agencySplitViewController.delegate = agencyDetail;
editoSplitViewController = [[UISplitViewController alloc] init];
editoRoot = [[[EI_iPad_News_Root_ViewController alloc] init] autorelease];
editoDetail = [[[EI_iPad_News_Detail_ViewController alloc] init] autorelease];
editoRootNav = [[[EI_Navigation_ViewController alloc] initWithRootViewController:editoRoot]autorelease];
editoDetailNav = [[[EI_Navigation_ViewController alloc] initWithRootViewController:editoDetail] autorelease];
editoSplitViewController.viewControllers = [NSArray arrayWithObjects:editoRootNav, editoDetailNav, nil];
editoSplitViewController.delegate = editoDetail;
searchSplitViewController.tabBarItem.title = NSLocalizedString(#"TabBar_search_label",nil);
searchSplitViewController.tabBarItem.image = [UIImage imageNamed:#"tabBar_search_icon.png"];
favoritesSplitViewController.tabBarItem.title = NSLocalizedString(#"TabBar_favorite_label",nil);
favoritesSplitViewController.tabBarItem.image = [UIImage imageNamed:#"tabBar_favorite_icon.png"];
agencySplitViewController.tabBarItem.title = NSLocalizedString(#"TabBar_agencies_label",nil);
agencySplitViewController.tabBarItem.image = [UIImage imageNamed:#"tabBar_agencies_icon.png"];
editoSplitViewController.tabBarItem.title = NSLocalizedString(#"TabBar_news_label",nil);
editoSplitViewController.tabBarItem.image = [UIImage imageNamed:#"tabBar_news_icon.png"];
tabBarController.viewControllers = [NSArray arrayWithObjects:searchSplitViewController,favoritesSplitViewController,agencySplitViewController,editoSplitViewController,nil];
[window addSubview:[tabBarController view]];
I want to add a fifth item which will display a popover... any idea ? Thanks

To get my UITabBarItem frame I noticed that on the iPad (on iPhone items are autorisizingWidth it's more simple) items are 75px width and are spaced by 34px.
So I do :
(tabBar.frame.size.width-((75*[tabBarController.items count])+(34*[tabBarController.items count]-1)))/2
to get the first flexible sapce width.
Then I add :
(75*indexOfItemToReach)+(34*(indexOfItemToReach-1))+(75/2)
To get the width center of the item.

I would advice against this because that's not the expected behavior for a tab bar. However, you could create a UIPopoverController and display it using presentPopoverFromRect.
UIPopoverController *pop = [[UIPopoverController alloc] initWithContentViewController:someVC];
[pop presentPopoverFromRect:CGRectMake(100,100,100,100) permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

You can crawl the tab bar's view hierarchy and look for UIControl subclasses (they may come up in random order, so you'll want to sort them by which one's center.x is leftmost). Each one is a tab bar button, which will have a rect.
This approach appears to be within the realm of App Store-safe coding, particularly if you fall back to just using the tab bar's frame if an OS upgrade breaks your code.
UIView has a handy undocumented method called recursiveDescription that's incredibly useful for debugging. E.g.:
(gdb) po [[[[[UIApplication sharedApplication] delegate] tabBarController] view] recursiveDescription]

Related

create navigationbar dynamatically in ios

This is the static navigation bar how i set in my project , but want to do in dynamic way, here is the two type of code...
viewsArray = [[NSArray alloc] init];
AfterloginViewController *toolsnavigation = [[AfterloginViewController alloc] init];
toolsnavigation.tabBarItem.image = [UIImage imageNamed:#"cool.png"];
[toolsnavigation setTitle:#"Tools"];
UINavigationController *nav0 = [[UINavigationController alloc] initWithRootViewController:toolsnavigation];
MapViewController *myridenavigation = [[MapViewController alloc] init];
myridenavigation.tabBarItem.image = [UIImage imageNamed:#"cool.png"];
[myridenavigation setTitle:#"Login"];
UINavigationController *nav1 = [[UINavigationController alloc] initWithRootViewController:myridenavigation];
viewsArray = [NSArray arrayWithObjects:nav0,nav1,nav2,nav3,nav4,nav5,nav6,nav7,nav8, nil];
tabbarController = [[UITabBarController alloc] init];
[tabbarController setViewControllers:viewsArray];
self.window.rootViewController = tabbarController;
Now i am getting data from the URL and want to assign it as dynamically navigation item. But i m puzzeled now, any idea how to do it.
NSString *loginstring = [NSString stringWithFormat:#"%#nvgationarray.php",mydomainurl];
NSMutableData *dataURL = [NSData dataWithContentsOfURL: [ NSURL URLWithString: loginstring]];
NSDictionary *allData = [NSJSONSerialization JSONObjectWithData:dataURL options:0 error:nil];
int i = 0;
for(NSDictionary *stat in allData)
{
NSString *ssprst = [stat objectForKey:#"tab_type"];
NSString *ssprst1 = [stat objectForKey:#"tab_name"];
NSString *ssprst2 = [stat objectForKey:#"tab_id"];
NSString *ssprst3 = [stat objectForKey:#"icon"];
NSLog(#"all data ===== :::: %# %# %# %#",ssprst,ssprst1,ssprst2,ssprst3);
NSLog(#"++++++++++++++++++++++++++++++++++++++++++++++");
AbcViewController *myridenavigation = [[AbcViewController alloc] init];
myridenavigation.tabBarItem.image = [UIImage imageNamed:#"cool.png"];
[myridenavigation setTitle:#"Login"];
UINavigationController *nav1 = [[UINavigationController alloc] initWithRootViewController:myridenavigation];
i++;
}
if you want to retain memory UINavigationController . I suggest you hold it in NSMutableArray.
In header file
#property(nonatomic, strong) NSMutableArray* arrayNavigationCont;
In implementation file
#synthesize arrayNavigationCont = _arrayNavigationCont;
do not forget also to init array in somewhere relevant like viewDidLoad
self.arrayNavigationCont = [[NSMutableArray alloc] init];
In your method
...
for(NSDictionary *stat in allData)
{
...
AbcViewController *myridenavigation = [[AbcViewController alloc] init];
myridenavigation.tabBarItem.image = [UIImage imageNamed:#"cool.png"];
[myridenavigation setTitle:#"Login"];
UINavigationController *nav1 = [[UINavigationController alloc] initWithRootViewController:myridenavigation];
[self.arrayNavigationCont addObject:nav1]
i++;
}
Later you can access you navigationConts somewhere again
for(int i = 0; i < [self.arrayNavigationCont count]; i++)
{
UINavigationController *nav1 = [self.arrayNavigationCont objectAtIndex:i];
//do sth with nav1 to your like
}

custom tabbar in xcode

i am new in xcode development. I want to create a custom tab bar not using the tabbar application or using the storyboard , i want to make it programmatically . Can it be possible. I have go-through with this Video Tutorial but when i am trying to release the tab, there giving error. Can anyone help me.Here is my code,
main_tab = [[UITabBarController alloc] init];
viewController1 = [[Firstview alloc] init];
viewController1.title = #"View 1";
UINavigationController *nav1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
viewController2 = [[SecondView alloc] init];
viewController2.title = #"View 2";
UINavigationController *nav2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
And i am using xcode 4.2
When using ARC, you do not need to retain or release objects anymore.
You can enable or disable ARC by clicking on the project file and selecting the corresponding property. Here you have a good description.
if you are using storyboard then there should be starting point.
so take a uitabarcontroller in storyboard as starting point and link a reference to tabBarController
NSMutableArray *listOfViewControllers = [[NSMutableArray alloc] init];
UIViewController *vc;
vc = [[UIViewController alloc] init];
vc.title = #"A";
[listOfViewControllers addObject:vc];
[vc release];
vc = [[UIViewController alloc] init];
vc.title = #"B";
[listOfViewControllers addObject:vc];
[vc release];
vc = [[UIViewController alloc] init];
vc.title = #"C";
[listOfViewControllers addObject:vc];
[vc release];
[self.tabBarController setViewControllers:listOfViewControllers
animated:YES];
}
Without storyboard and without taking UITabbarController in XIB
UITabBarController *tabBarController = [[UITabBarController alloc] init];
NSMutableArray *listOfViewControllers = [[NSMutableArray alloc] init];
UIViewController *vc;
vc = [[UIViewController alloc] init];
vc.title = #"A";
[listOfViewControllers addObject:vc];
[vc release];
vc = [[UIViewController alloc] init];
vc.title = #"B";
[listOfViewControllers addObject:vc];
[vc release];
vc = [[UIViewController alloc] init];
vc.title = #"C";
[listOfViewControllers addObject:vc];
[vc release];
[tabBarController setViewControllers:listOfViewControllers
animated:YES];

iphone UITabBarController memory management

In my function - (void)viewDidLoad:
FirstViewController *first = [[FirstViewController alloc]init];
SecondViewController *second = [[SecondViewController alloc]init];
ThirdViewController *third = [[ThirdViewController alloc]init];
ForthViewController *forth = [[ForthViewController alloc]init];
FifthViewController *fifth = [[FifthViewController alloc]init];
first.tabBarItem = [[UITabBarItem alloc]initWithTitle:#"first" image:[UIImage imageNamed:#"FirstTab.png"] tag:0];
second.tabBarItem = [[UITabBarItem alloc]initWithTitle:#"second" image:[UIImage imageNamed:#"SecondTab.png"] tag:1];
third.tabBarItem = [[UITabBarItem alloc]initWithTitle:#"third" image:[UIImage imageNamed:#"ThirdTab.png"] tag:2];
forth.tabBarItem = [[UITabBarItem alloc]initWithTitle:#"forth" image:[UIImage imageNamed:#"ForthTab.png"] tag:3];
fifth.tabBarItem = [[UITabBarItem alloc]initWithTitle:#"fifth" image:[UIImage imageNamed:#"FifthTab.png"] tag:3];
UINavigationController *navigationFirst = [[UINavigationController alloc]initWithRootViewController:first];
UINavigationController *navigationSecond = [[UINavigationController alloc]initWithRootViewController:second];
UINavigationController *navigationThird = [[UINavigationController alloc]initWithRootViewController:third];
UINavigationController *navigationForth = [[UINavigationController alloc]initWithRootViewController:forth];
UINavigationController *navigationFifth = [[UINavigationController alloc]initWithRootViewController:fifth];
// [first release];
// [second release];
// [third release];
// [forth release];
// [first release];
NSMutableArray *array = [[NSMutableArray alloc]initWithObjects:navigationFirst,navigationSecond,navigationThird,navigationForth,navigationFifth, nil];
[navigationFirst release];
[navigationSecond release];
[navigationThird release];
[navigationForth release];
[navigationFifth release];
self.tabbarController = [[UITabBarController alloc]init];
self.tabbarController.view.frame = CGRectMake(0, 0, 320, 480);
self.tabbarController.viewControllers = array;
[array release];
I intend to add five UINavigationControllers to tabcontroller,if I don't comment the fellowing code,it will crash:
// [first release];
// [second release];
// [third release];
// [forth release];
// [first release];
but I want to know what's the problem,I think it is correct to add thees code.
you are releasing first object twice. thats why your code is crashing.
replace [first release] with [fifth release]
You should release Navigation controllers in the end
UINavigationController *navigationFirst = [[UINavigationController alloc]initWithRootViewController:first];
UINavigationController *navigationSecond = [[UINavigationController alloc]initWithRootViewController:second];
UINavigationController *navigationThird = [[UINavigationController alloc]initWithRootViewController:third];
UINavigationController *navigationForth = [[UINavigationController alloc]initWithRootViewController:forth];
UINavigationController *navigationFifth = [[UINavigationController alloc]initWithRootViewController:fifth];
[first release];
[second release];
[third release];
[forth release];
[first release];
NSMutableArray *array = [[NSMutableArray alloc]initWithObjects:navigationFirst,navigationSecond,navigationThird,navigationForth,navigationFifth, nil];
self.tabbarController = [[UITabBarController alloc]init];
self.tabbarController.view.frame = CGRectMake(0, 0, 320, 480);
self.tabbarController.viewControllers = array;
[navigationFirst release];
[navigationSecond release];
[navigationThird release];
[navigationForth release];
[navigationFifth release];
[array release];

Putting a ViewController on top of a TabBarController

Basically I want to make a login screen in my iPhone app before I show my TabBarController. I tried the following approach, adding first to the window subview my TabBarController and on top my LoginViewController. What am I doing wrong or should I do it completely different?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[self.window makeKeyAndVisible];
NSMutableArray *tabItems = [[NSMutableArray alloc] initWithCapacity:2];
DefaultViewController *dvc = [[DefaultViewController alloc] init];
UINavigationController *dvc_nc = [[UINavigationController alloc] initWithRootViewController:dvc];
dvc_nc.tabBarItem.title = #"Home";
//dvc_nc.tabBarItem.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Default" ofType:#"png"]];
[tabItems addObject:dvc_nc];
[dvc release];
[dvc_nc release];
OptionsViewController *ovc = [[OptionsViewController alloc] initWithStyle:UITableViewStyleGrouped];
UINavigationController *ovc_nc = [[UINavigationController alloc] initWithRootViewController:ovc];
ovc_nc.tabBarItem.title = #"Option";
//ovc_nc.tabBarItem.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Option" ofType:#"png"]];
[tabItems addObject:ovc_nc];
[ovc release];
[ovc_nc release];
UITabBarController *tbc = [[UITabBarController alloc] init];
tbc.viewControllers = tabItems;
self.tabController = tbc;
[tabItems release];
[tbc release];
[self.window addSubview:self.tabController.view];
LoginViewController *lvc = [[OptionsViewController alloc] init];
UINavigationController *lvc_nc = [[UINavigationController alloc] initWithRootViewController:lvc];
[self.window addSubview:lvc_nc.view];
[lvc release];
[lvc_nc release];
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[self.window makeKeyAndVisible];
NSMutableArray *tabItems = [[NSMutableArray alloc] initWithCapacity:2];
DefaultViewController *dvc = [[DefaultViewController alloc] init];
UINavigationController *dvc_nc = [[UINavigationController alloc] initWithRootViewController:dvc];
dvc_nc.tabBarItem.title = #"Home";
//dvc_nc.tabBarItem.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Default" ofType:#"png"]];
[tabItems addObject:dvc_nc];
[dvc release];
[dvc_nc release];
OptionsViewController *ovc = [[OptionsViewController alloc] initWithStyle:UITableViewStyleGrouped];
UINavigationController *ovc_nc = [[UINavigationController alloc] initWithRootViewController:ovc];
ovc_nc.tabBarItem.title = #"Option";
//ovc_nc.tabBarItem.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Option" ofType:#"png"]];
[tabItems addObject:ovc_nc];
[ovc release];
[ovc_nc release];
UITabBarController *tbc = [[UITabBarController alloc] init];
tbc.viewControllers = tabItems;
self.tabController = tbc;
[tabItems release];
[tbc release];
[self.window addSubview:self.tabController.view];
LoginViewController *lvc = [[OptionsViewController alloc] init];
UINavigationController *lvc_nc = [[UINavigationController alloc] initWithRootViewController:lvc];
[self.tabController presentModalViewController:lvc_nc animated:no];
[lvc release];
[lvc_nc release];
return YES;
}
I would use two different views. One will handle the login proccess and one is your "Logged in view" that provides the features of your app. When your app starts up, you add the login view, check username/password and when the login went fine you switch to your second view.

Programmatically Setting UITabBar Titles

i had programetically add the tabbar as shown below:-
FirstViewController *obj_FirstViewController = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil]; SecondViewController *obj_SecondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil]; ThirdViewController *obj_ThirdViewController = [[ThirdViewController alloc] initWithNibName:#"ThirdViewController" bundle:nil];
navigation1 = [[UINavigationController alloc] initWithRootViewController:obj_FirstViewController];
navigation2 = [[UINavigationController alloc] initWithRootViewController:obj_SecondViewController];
navigation3 = [[UINavigationController alloc] initWithRootViewController:obj_ThirdViewController];
MainTabBar = [[UITabBarController alloc] init];
MainTabBar.delegate=self;
[MainTabBar setViewControllers:[NSArray arrayWithObjects:navigation1,navigation2,navigation3,nil]];
MainTabBar.view.frame=self.view.frame;
MainTabBar.selectedIndex=0;
[self.view addSubview:MainTabBar.view]
By writing this in (void)viewDidLoad i got the 3 tab in my viewcontroller. But the problem is i want to set the name of the tab as 1)Home 2)Favorites 3)About us
I had tried by writing the below code:
- 1)obj_FirstViewController.tabBarItem.title=#"Home"; 2)self.title = #"My View Controller";
But this does not work. Can anyone please help me how to do this programtically. Where to write the line so that i get this 3 name in my tabbar
Try this way...
NSMutableArray *controllers = [[NSMutableArray alloc] init];
FirstViewController *obj_FirstViewController = [[FirstViewController alloc] init];
[obj_FirstViewController setTitle:#"first"];
UITabBarItem *item = [[[UITabBarItem alloc] setTabBarItem: [[[UITabBarItem alloc] initWithTitle: #"First") image:[UIImage imageNamed:#"first.png"] tag:2] autorelease]];
[obj_FirstViewController setTabBarItem:item];
[controllers addObject:obj_FirstViewController];
[obj_FirstViewController release];
Pls Try this
FirstViewController *obj_FirstViewController = [[FirstViewController alloc]initWithNibName:#"FirstViewController" bundle:nil];
SecondViewController *obj_SecondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
ThirdViewController *obj_ThirdViewController = [[ThirdViewController alloc] initWithNibName:#"ThirdViewController" bundle:nil];
navigation1 = [[UINavigationController alloc] initWithRootViewController:obj_FirstViewController];  
navigation2 = [[UINavigationController alloc] initWithRootViewController:obj_SecondViewController];
navigation3 = [[UINavigationController alloc] initWithRootViewController:obj_ThirdViewController];
navigation1.title=#"Home";
navigation2.title=#"Second";
MainTabBar = [[UITabBarController alloc] init];
MainTabBar.delegate=self;
[MainTabBar setViewControllers:[NSArray arrayWithObjects:navigation1,navigation2,navigation3,nil]];
MainTabBar.view.frame=self.view.frame;
MainTabBar.selectedIndex=0;
[self.view addSubview:MainTabBar.view]