Getting a UITabBar after breaking out of a UINavigationBar - ios

I have a UINavigationBar that has an AuthenticateViewController in it. Then when the user his Sign In in the upper right of my navigation control, I want to show a UITabBar controller. Do I still create this in appDelegate? How do I "break out" of the UINavigation controller?
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// Add methods for layout of this view controller here
//1
AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
//2
self.managedObjectContext = appDelegate.managedObjectContext;
[self.navigationItem setHidesBackButton:YES];
// Now add the Sign In button
UIBarButtonItem *signinButton = [[UIBarButtonItem alloc] initWithTitle:#"Sign In" style:UIBarButtonItemStylePlain target:self action:#selector(signinButtonPressed:)];
self.navigationItem.rightBarButtonItem = signinButton;
}
- (void) signinButtonPressed:(UIBarButtonItem *) sender
{
// What goes here to start the UITabBars
}

Set your TabBarController as rootViewController after signed in.
Your button action would be like this:
UITabBarController *tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = #[<your viewControllers>];
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate.window setRootViewController:tabBarController];
Edit: You might don't get use with array creation with #[]. So here is an explanation:
UIViewController *viewController1 = [[UIViewController alloc] init];
UIViewController *viewController2 = [[UIViewController alloc] init];
// Two methods of adding item to array
// First method
NSArray *array = [NSArray arrayWithObjects:viewController1, viewController2, nil];
// or
NSArray *array = #[viewController1, viewController2];
tabBarController.viewControllers = array;

You'll need to do a modalTransition to jump out of the navigationController.. this will keep the AuthenticateViewController as RootViewController of the window.. if you want to change the RootViewController as well then you'll need to get the AppDelegate's window and change its RootViewController to the TabBarController you'll make hereā€¦ hope you got it..

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];

how to add tab bar controller from the second view controller [duplicate]

This question already has an answer here:
Showing login view controller before main tab bar controller
(1 answer)
Closed 9 years ago.
Im beginner to IOS app development learning.
I have a login screen as my first view controller and i need the second view controller to be a tab bar view controller .with 4 different tabs and i have 4 different XIB's for them.
some one help me to go ahead.
Best way you can do is Present the login screen modally when the app starts from your tab bar controller first screen, add code for presenting login screen in viewWillAppear and after login dismiss the screen. You can create TabBarController in appDelegate like this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UITabBarController tabBarController=[[UITabBarController alloc] init];
FirstViewController *firstVC = [[UIViewController alloc] initWithNibName:#"FirstVC" bundle:nil];
UINavigationController *firstNavController = [[UINavigationController alloc] initWithRootViewController: firstVC];
SecondViewController *secondVC = [[UIViewController alloc] initWithNibName:#"secondVC" bundle:nil];
UINavigationController *secondNavController = [[UINavigationController alloc] initWithRootViewController:secondVC];
tabBarController.viewControllers = [NSArray arrayWithObjects: firstNavController, secondNavController, nil];
tabBarController.selectedIndex=0;
tabBarController.delegate = self;
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:#"Movies" image:[UIImage imageNamed:#"MoviesTAB.png"] tag:1];
[firstVC setTabBarItem:item1];
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:#"Music" image:[UIImage imageNamed:#"musicTAB.png"] tag:2];
[seconfVC setTabBarItem:item2];
tabController.tabBar.translucent = NO;
tabController.tabBar.barStyle = UIBarStyleBlack;
tabBarController.tintColor = [UIColor whiteColor];
self.window.rootViewController = tabController;
return YES;
}
Best way is use storyboard and there just have one initial UIViewController and from that make segue to UITabBarViewController.
http://youtu.be/a_DCTSTv1Mw
If you want to make it through xib make a UITabBarViewController and add viewControllers to the array of object of that UITabBarViewController's object.
Sample code :
NSMutableArray *arrViewControllers = [[NSMutableArray alloc] init];
UIViewController *tabController;
UIImage *tabImage ;
NSString *tabTitle;
for (int i= 0; i < 3; i++) {
switch (i) {
case 0:
tabController = [[ViewController alloc] init];
tabImage = [UIImage imageNamed:#"icon1.png"];
tabTitle = #"Text";
break;
case 1:
tabController = [[ImageDemoViewController alloc] init];
tabImage = [UIImage imageNamed:#"icon2.png"];
tabTitle = #"Image";
break;
case 2:
tabController = [[TableDemoViewController alloc] init];
tabImage = [UIImage imageNamed:#"icon3.png"];
tabTitle = #"Table";
break;
}
// set the image and title using some properties of UIViewController
tabController.tabBarItem.image = tabImage;
tabController.tabBarItem.title = tabTitle;
//add objects to array
[arrViewControllers addObject:tabController];
[tabController release];
}
_baseController = [[UITabBarController alloc] init];
_baseController.viewControllers = arrViewControllers;
[arrViewControllers release];
go to your appDelegate
1.create a viewController for login screen.
LoginViewController *viewController1 = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
2.create a navigationController with root view your login ViewController.
UINavigationController *nVC = [[UINavigationController alloc] initWithRootViewController:viewController1];
3.make navigationController to root view of window.
self.window.rootViewController = self.nVC;
[self.window makeKeyAndVisible];
Now go to Touch-Up-Inside method of login button in LoginViewController.
1.After validation of password and userId initialise your viewControllers for tabbar and TabbarViewController.
UiViewController ...*yourViewControllers,..,
UITabBarController *YourtabBarController = [[UITabBarController alloc] init];
2.Now add these viewControllers to your tabbarController.
YourtabBarController.viewControllers = #[ YourViewController1,YourViewController2,YourViewController3,......];
3.Finally push this tabbarController to navigationControllere.
[self.navigationController pushViewController:YourtabBarController animated:NO];

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];
}

Navigation Controller loading twice, how to resolve this?

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;
}

Create uiTabBarController programmatically

I want to create a UIView for a UITabBarController
Here is my code for the .h file :
#interface TE : UIViewController <UITabBarControllerDelegate>{
UITabBarController *tabBarController;
}
#property (nonatomic,retain) UITabBarController *tabBarController;
#end
The viewDidLoad method:
UIViewController *testVC = [[T1 alloc] init];
UIViewController *otherVC = [[T2 alloc] init];
NSMutableArray *topLevelControllers = [[NSMutableArray alloc] init];
[topLevelControllers addObject: testVC];
[topLevelControllers addObject: otherVC];
tabBarController = [[UITabBarController alloc] init];
tabBarController.delegate = self;
[tabBarController setViewControllers:topLevelControllers animated:NO];
tabBarController.selectedIndex = 0;
self.view = tabBarController.view;
This creates the tab bar controller, but when I click on a tab bar item, I get an error:
Thread1:Program receive signal: SIGABRT
Edit: I solved the problem by downloading and modifying the version of http://www.iphonedevcentral.com/create-uitabbarcontroller/
You say above that you don't want to create the tabBarController in the appDelegate. Why not? Where else would you create it? The tabBarController has to be the root view controller and cannot be a child of any other view controller.
Btw, make sure you implement:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
NSUInteger tabIndex = [tabBarController.viewControllers indexOfObject:viewController];
if (viewController == [tabBarController.viewControllers objectAtIndex:tabIndex] ) {
return YES;
}
return NO;
}
Subclass UITabBarController
Override the - (void) loadView method and include the following code
MyCustomViewControllerOne* ctrl1 = [[[MyCustomViewControllerOne alloc] initWithNibName#"MyViewControllerOne" bundle: nil] autorelease];
UIViewController* ctrl2 = [[[UIViewController alloc] init] autorelease];
MyCustomControllerTwo* ctrl3 = [[[UIViewController alloc] initWithObject: myObj] autorelease];
ctrl1.title = #"First tab";
ctrl2.title = #"Second tab";
ctrl3.title = #"Third tab";
ctrl1.tabBarItem.image = [UIImage imageNamed:#"tab_image1.png"];
ctrl2.tabBarItem.image = [UIImage imageNamed:#"tab_image2.png"];
ctrl3.tabBarItem.image = [UIImage imageNamed:#"tab_image3.png"];
[self setViewControllers: #[ctrl1, ctrl2, ctrl3]];
That's pretty much it.
Change self.view = tabBarController.view; to
[self.view addSubview:tabBarController.view]; And it works correctly
Trying changing
self.view = tabBarController.view;
to
[self.view addSubview:tabBarController.view];
See if that helps.
Also try placing this in your -(void)loadView method
- (void)loadView {
UIView *mv = [[UIView alloc] initWithFrame:CGRectMake(0.0, 100.0, 320.0, 480.0)];
self.view = mv;
[mv release];
}
The reason you probably are experiencing a black screen is because you haven't initialized your UIView properly.
#Mehdi, just make your TE a UITabBarController instead of a UIViewController which then has a TabBarController in it. Makes it all the more easy to manage your TabBarController. To respond to some others who have indicated that you can have only one TabBarController as the window's rootViewController. That is not the case. A UITabBarController can be instantiated in multiple places where you need a second level menu navigation. Have a TabBar within a TabBar would not make sense, but having a left Navigation Menu and then having a TabBar on each menu item would make sense.

Resources