Navigation Controller loading twice, how to resolve this? - ios

my project contains navigation controller and segmented control (with separate view controller: segmentManagingViewController) programmatically and now i added a tab bar in IB..while calling tab bar controller and navigation controller ,segmentManagingViewController view getting loaded twice.. both in tab bar item1 and in first segment i have called segmentManagingViewController view ....
here is screen shot of my app
and following is
application didFinishLaunchingWithOptions method... please do help me out to resolve this ...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
databaseName = #"breadworks.sql";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
[self checkAndCreateDatabase];
[self readBreadsFromDatabase];
[self categoryFromDatabase];
SegmentManagingViewController * segmentManagingViewController = [[SegmentManagingViewController alloc] init];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:segmentManagingViewController];
[segmentManagingViewController release];
[self.window addSubview:tabBarController.view];
[window addSubview: navigationController.view];
[window makeKeyAndVisible];
return YES;
}

Your code sounds strange to me.
First, since you use an UITabBarController set it as the rootViewController for your window.
Then, set the UINavigationController as a child controller of your tab bar controller.
Finally, as you did, set the rootViewController for your UINavigationController to segmentManagingViewController.
Now, since I prefer to do it without xib you could do the following.
UITabBarController* tabBarController = [[UITabBarController alloc] init];
SegmentManagingViewController * segmentManagingViewController = [[SegmentManagingViewController alloc] init];
UINavigationController* navigationController = [[UINavigationController alloc] initWithRootViewController:segmentManagingViewController];
tabBarController.viewControllers = [NSArray arrayWithObjects:navigationController, nil];
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];
//- only if you don't use ARC -----
[segmentManagingViewController release];
[navigationController release];
[tabBarController release];
//----------------------------------
return YES;
If don't use ARC make attention to memory management!!
Hope it helps.

I declared navigation controller and view controllers (which are used as objects of NSArray) in delegate and created initWithNibName Constructor for view controllers( defining Title, Image and other properties of TabBarItems).. here is the updated code chunks ..
UIViewController *viewController1 = [[AtoZSecondviewController alloc] initWithNibName:#"AtoZSecondviewController" bundle:nil];
UIViewController *viewController2 = [[CategorySecondViewController alloc] initWithNibName:#"CategorySecondViewController" bundle:nil];
tabBarController.viewControllers = [NSArray arrayWithObjects:navigationController,viewController1 ,viewController2, nil];
following is Definition of initWithNibName in ViewControllers
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if (self) {
self.title = NSLocalizedString(#"Catogaries", #"Catogaries");
self.tabBarItem.image = [UIImage imageNamed:#"TodaysChoice"];
}
return self;
}

Related

How to change positions of UITabBarItems according to certain situations in the app, programmatically

I have 3 items in my UITabBar and my app runs 2 Languages(English and Arabic). I need to change the position of the items when the app is switched to Arabic since A Right to Left reading is required
ie. the Tab called "One Way" must appear at the right side and Multi City has to appear at the left side. Is there a way to do that?
I tried this method but That was not allowed
UITabBarItem *realItemOne=[self.tabBar.items objectAtIndex:0];
UITabBarItem *realItemTwo=[self.tabBar.items objectAtIndex:1];
UITabBarItem *realItemThree=[self.tabBar.items objectAtIndex:2];
if (_isEnglish) {
self.tabBar.items=[[NSArray alloc] initWithObjects:realItemOne,realItemTwo,realItemThree, nil];
}
else{
self.tabBar.items=[[NSArray alloc] initWithObjects:realItemThree,realItemTwo,realItemOne, nil];
}
Also Tried this
self.tabBar.items=[[self.tabBar.items reverseObjectEnumerator] allObjects];
Another method that I tried
UIViewController *viewControllerOne=[self.tabBarController.viewControllers objectAtIndex:0];
UIViewController *viewControllerTwo=[self.tabBarController.viewControllers objectAtIndex:1];
UIViewController *viewControllerThree=[self.tabBarController.viewControllers objectAtIndex:2];
if (_isEnglish) {
NSArray *englishOrder=[[NSArray alloc] initWithObjects:viewControllerOne,viewControllerTwo,viewControllerThree, nil];
[self.tabBarController setViewControllers:englishOrder];
}
else{
NSArray *arabicOrder=[[NSArray alloc] initWithObjects:viewControllerThree,viewControllerTwo,viewControllerOne, nil];
[self.tabBarController setViewControllers:arabicOrder];
}
Do not change items, change just text and image of tab item.
if (_isEnglish) { change just image and text on 0. and 2. tab } else { also just change image and text }
when the user tap on the item, you check for language and then do appropriate method. If user tap on 0. element and the language is english, you call oneWay method and if language is arabic you call multiCity
I hope this helps.
You can get the number of controllers in tabBarController in NSArray format as below:
NSArray *vcArray = self.tabBarController.viewControllers;
Now change the sequence of the objects of this "vcArray" as you want(for demo purpose I have used 3 controllers. you can put your logic whatever you want) and then re-assign "vcArray" to your tabBarController like below:
self.tabbarController.viewControllers = vcArray;
Actual code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
FirstViewController *fvc = [[FirstViewController alloc] init];
SecondViewController *svc = [[SecondViewController alloc] init];
ThirdViewController *tvc = [[ThirdViewController alloc] init];
fvc.tabBarItem.title = #"First";
svc.tabBarItem.title = #"Second";
tvc.tabBarItem.title = #"Third";
_tbc = [[UITabBarController alloc] init];
_tbc.viewControllers = [NSArray arrayWithObjects:fvc, svc, tvc, nil];
self.window.rootViewController = _tbc;
[self.window makeKeyAndVisible];
return YES;
}
--------------- A method to swap controllers in tabViewController in AppDelegate -----------
NSArray *arr = self.tbc.viewControllers; //here self means appDelegate
self.tbc.viewControllers = [NSArray arrayWithObjects:arr[2], arr[1], arr[0], nil];
Hope this helps!
Attached images for your reference.
This worked for me:
Place this code in the TabBArController ViewWillAppear method
NSArray *actualItems= self.viewControllers;
NSArray* reversedArray = [[actualItems reverseObjectEnumerator] allObjects];
[self setViewControllers:reversedArray animated:YES];

MHTabBarController add to uiviewcontroller

Im trying to use the MHTabBarController https://github.com/hollance/MHTabBarController
, in the example the custom view controller is added as a rootViewController in app delegate,
i want to add 3 tabs inside a standard tab bar controller's view for example MainViewController
here is my code inside viewDidLoad in MainViewController.m:
//MHTabBarController config
ListViewController *listViewController1 = [[ListViewController alloc] initWithStyle:UITableViewStylePlain];
ListViewController *listViewController2 = [[ListViewController alloc] initWithStyle:UITableViewStylePlain];
ListViewController *listViewController3 = [[ListViewController alloc] initWithStyle:UITableViewStylePlain];
listViewController1.title = #"Tab 1";
listViewController2.title = #"Tab 2";
listViewController3.title = #"Tab 3";
NSArray *viewControllers = #[listViewController1, listViewController2, listViewController3];
MHTabBarController *tabBarController = [[MHTabBarController alloc] init];
tabBarController.delegate = self;
tabBarController.viewControllers = viewControllers;
[self.view addSubview:tabBarController.view];
ive also added the in MainViewController.h
but its not working, its showing a table but not the tabs on top.
what im missing?
That code should go inside the AppDelegate.m
Something like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
MainViewController *mainViewController = [[MainViewController alloc] init];
mainViewController.title = #"Main Tab";
NSArray *viewControllers = #[mainViewController];
MHTabBarController *tabBarController = [[MHTabBarController alloc] init];
tabBarController.delegate = self;
tabBarController.viewControllers = viewControllers;
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
This way you're adding a the tab bar into the MainViewController, if you wanna add the same tab bar into other view controllers, just add the view controllers into the viewControllers array.

How to reorder TabBar's Tabs programmatically?

Is there a way to reorder tabs of a TabBar programmatically on xCode?
Thank you a lot, Matteo!
Try this:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
tabBarController = [[UITabBarController alloc] init];
MyViewController* vc1 = [[MyViewController alloc] init];
MyOtherViewController* vc2 = [[MyOtherViewController alloc] init];
NSArray* controllers = [NSArray arrayWithObjects:vc1, vc2, nil];
tabBarController.viewControllers = controllers;
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
}

UITabBarController - more button does not show up

I create my TabBarController programatically, because I want the same Controller in every tab displaying different content. The content is fetched by an ID.
I use the storyboard id the same way as one would use initWithNibName:.
I do this in the AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
for (int i = 0; i < 7; i++) {
MyViewController *svc = [storyboard instantiateViewControllerWithIdentifier:#"MyView"];
[svc setID: i];
[tabBarController addChildViewController:svc];
}
[self.window makeKeyAndVisible];
[self.window setRootViewController: tabBarController];
return YES;
}
But the TabBar shows only 5 of the 7 Tabs. This is fine, because only 5 tabs can be visible the same time. Unfortunately the ... More button is not visible. So the last 2 tabs are not accessible.
Does anyone have an idea how to force the More button to show up, or why it does not show up?
Regards!
It's not showing up because you are adding viewcontrollers to the tab bar controller using addChildViewController method which is a UIViewController method and not a tab bar controller method. So i think what's happening is the tab bar controller doesn't really know that it has more than 5 view controllers.
If you want the more view controller to show up, set the viewControllers array of the tab bar controller directly. Modify your code to something like below:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
NSMutableArray *vcArray = [NSMutableArray array];
for (int i = 0; i < 7; i++) {
ViewController *svc = [storyboard instantiateViewControllerWithIdentifier:#"MyView"];
[svc setID: i];
[vcArray addObject:svc];
}
[tabBarController setViewControllers:vcArray]; //This is the important part.
[self.window setRootViewController: tabBarController];
[self.window makeKeyAndVisible];
Following is simple example for How can you use UITabBarController
Firsts Create all object of UIViewController and UINavigationController in AppDelegate.h file and use following method of AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window=[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds ]];
self.viewCon=[[ViewController alloc] init];
self.navCon=[[UINavigationController alloc] initWithRootViewController:self.viewCon];
self.navCon.navigationBar.tintColor=[UIColor blackColor];
self.viewCon.title=#"First View";
self.fView=[[FirstViewController alloc] init];
self.FnavCon=[[UINavigationController alloc] initWithRootViewController:self.fView];
self.FnavCon.navigationBar.tintColor=[UIColor blackColor];
self.fView.title=#"Secound View";
self.sView=[[SecoundViewController alloc] init];
self.SnavCon=[[UINavigationController alloc] initWithRootViewController:self.sView];
self.SnavCon.navigationBar.tintColor=[UIColor blackColor];
self.sView.title=#"Third View";
.
.
// create UIViewController and UINavigationController As you need
.
.
.
UIImage *img1=[UIImage imageNamed:#"Australia.gif"];
self.tbItem1=[[UITabBarItem alloc] initWithTitle:#"First Page" image:img1 tag:1];
self.viewCon.tabBarItem=self.tbItem1;
UIImage *img2=[UIImage imageNamed:#"Cameroon.gif"];
self.tbItem2=[[UITabBarItem alloc] initWithTitle:#"Secound Page" image:img2 tag:2];
self.fView.tabBarItem=self.tbItem2;
UIImage *img3=[UIImage imageNamed:#"Canada.png"];
self.tbItem3=[[UITabBarItem alloc] initWithTitle:#"Third Page" image:img3 tag:3];
self.sView.tabBarItem=self.tbItem3;
NSMutableArray *viewArr=[[NSMutableArray alloc] init];
[viewArr addObject:self.navCon];
[viewArr addObject:self.FnavCon];
[viewArr addObject:self.SnavCon];
self.tbCon=[[UITabBarController alloc] init];
self.tbCon.viewControllers=viewArr;
[self.window addSubview:tbCon.view];
[self.window makeKeyAndVisible];
return YES;
}

Orientation Problem while using insertSubview

I get an orientation problem while using the following to code to display a view on top of a split view.
[window addSubview:aSplitViewController.view];
[window insertSubview:aViewController.view aboveSubview:aSplitViewController.view];
the plain view has a couple of buttons and labels.
So the problem I am facing is that the first view opens in landscape mode but the labels and buttons on the view are in portrait mode.
UPDATE: Here is some code so if anyone wants to see more details...
In my App Delegate
- (void) makeSplitViewController {
NSMutableArray *controllers = [NSMutableArray arrayWithArray:tabBarController.viewControllers];
// First tabbbar item
// detail view
detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
UINavigationController *navDetailView = [[[UINavigationController alloc] initWithRootViewController:detailViewController] autorelease];
navDetailView.hidesBottomBarWhenPushed = YES;
// root view
rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];
rootViewController.detailViewController = detailViewController;
rootViewController.navigationItem.title = #"List";
UINavigationController *navRootView = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease];
navRootView.hidesBottomBarWhenPushed = YES;
navRootView.navigationBar.barStyle = UIBarStyleBlackTranslucent;
splitViewController = [[UISplitViewController alloc] init];
splitViewController.tabBarItem.title = #"Face Sheet";
splitViewController.tabBarItem.image = [UIImage imageNamed:#"gear1.png"];
splitViewController.navigationItem.title = #"Face Sheet";
splitViewController.viewControllers = [NSArray arrayWithObjects:navRootView, navDetailView, nil];
splitViewController.delegate = detailViewController;
splitViewController.hidesBottomBarWhenPushed = YES;
[controllers addObject:splitViewController];
// Second tabbbar item
scoreViewController = [[ScoreCardViewController alloc] initWithNibName:#"TableViewController" bundle:nil];
scoreViewController.tabBarItem.title = #"Score Card";
scoreViewController.tabBarItem.image = [UIImage imageNamed:#"gear1.png"];
scoreViewController.navigationItem.title = #"Score Card";
[controllers addObject:scoreViewController];
tabBarController.viewControllers = controllers;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Create tabbar
tabBarController = [[UITabBarController alloc] init];
//tabBarController.delegate = self;
// Set window
[window addSubview:splashController.view];
[window insertSubview:tabBarController.view belowSubview:splashController.view];
[self.window makeKeyAndVisible];
application.statusBarOrientation = UIInterfaceOrientationLandscapeRight;
return YES;
}
and here is the code in my SplashScreenView
- (IBAction) proceedButtonClick:(id)sender
{
// Initialize loginpopview
PhysicianLoginViewController *loginViewController = [[PhysicianLoginViewController alloc] init];
popOverController = [[UIPopoverController alloc] initWithContentViewController:loginViewController];
popOverController.popoverContentSize = CGSizeMake(350, 200);
popOverController.delegate = self;
// Set a notification to dismiss it later
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(loginViewControllerDone:) name:#"loginViewControllerDone" object:popOverController.contentViewController];
// Present popover
if ([popOverController isPopoverVisible])
{
[popOverController dismissPopoverAnimated:YES];
}
else
{
[popOverController presentPopoverFromRect:CGRectMake(485, 600, 100, 100) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}
}
// Dismiss popview controller and setup the tabbar
- (void)loginViewControllerDone:(NSNotification *)notification{
[[NSNotificationCenter defaultCenter] removeObserver:self];
// Button in content view controller was tapped, dismiss popover...
[self.popOverController dismissPopoverAnimated:YES];
// remove subview
[self.view removeFromSuperview];
// set tabbar
i3EAppDelegate *appDelegate = (i3EAppDelegate *) [[UIApplication sharedApplication]delegate];
[appDelegate makeSplitViewController];
}
It would be great if someone could point out where I am going wrong. I have been stuck with this problem for quite a few days and I have tried everything that comes to my mind...
UIWindow has a subview that it uses for rotations and puts other views inside of that. You need to insert yourself into the root view (or something lower), not the window. Look at -[UIWindow rootViewController].
UIView *rootView = [[[self window] rootViewController] view];
[rootView addSubview:view];
This will work as long as you're using something with a root view controller. This will work as long as rootViewController isn't nil. If you're doing a raw "View Based" application, then it's usually best to pick another view and add your view as its sibling rather than digging through the undocumented hierarchy:
UIView *sibling = ... (some other view)
[[sibling superview] addSubview:view];

Resources