Difficulty displaying Tab Views in iOS iPhone - iphone

I'm new to iOS dev and I have a program that begins by presenting the user a view. This view has two buttons, and depending on which the user clicks, a different tab view will be displayed. The tab view is displayed like this:
betaAppDelegate* delegate = (betaAppDelegate*)[[UIApplication sharedApplication]delegate];
acquireData *ac_view = (acquireData*)[[acquireData alloc] init];
[delegate.window addSubview:ac_view.view];
[self.view removeFromSuperview];
[self dealloc];
The tab view is ac_view.view. When I run the application in the simulator, instead of displaying my tab view with three tabs, it displays a white screen with a thin black bar (empty tab dock) on the bottom. It's encouraging to at least see something be displayed! But I've been trying without success for a while to get it to display my tabs. The .xib file looks correct. It has the three tabs at the bottom, and each of the three tabs say in the interface builder that they're loaded from xxxxxxx, so the linking appears correct...
Thank you!

I'm going to presume you're using the UITabBarController.
You can either set one up by adding the tabs in interface builder and then setting which xibs the individual tabs load up. It sounds like you have done this. After that there is no code you need to write to get the tab bar working to switch between your three view controllers.
You can also set up the TabBarController programatically.
This would be the programmatic way and would go into you application delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
UITabBarController * aTabBarController = [[UITabBarController alloc] init];
NSArray * array = [[NSArray alloc] initWithObjects:controller1, controller2, controller3, nil];
[aTabBarController setViewControllers:array animated:NO];
[array release];
self.window.rootViewController = aTabBarController;
[self.window makeKeyAndVisible];
[aTabBarController release];
return YES;
}
You would then see a tab bar with three tabs that correspond to controller1, 2 and 3 (your custom view controllers)
To set the icon and text and things its as easy as reading the documentation and seeing
Tab bar items are configured through
their corresponding view controller.
To associate a tab bar item with a
view controller, create a new instance
of the UITabBarItem class, configure
it appropriately for the view
controller, and assign it to the view
controller’s tabBarItem property.
Just a final word of warning in Objective C you should never call dealloc yourself. Dealloc is called by the system when an objects retain count reaches 0. Read into how to retain and release objects to get the hang of how this all works.
Good luck

Related

Creating a TabBarControllerDelegate in a Storyboard

I'm having difficulty creating a UITabBarControllerDelegate in my Storyboard driven iOS5 application. Here is the situation:
I have an initial screen that will eventually handle login but which currently just has a button that sends the user to...
...a Tab Bar Controller with five tabs. Each of these tabs go to...
...a Navigation Controller with many child View Controllers under the root.
(If it helps, a screenshot of the relevant Storyboard section is here.)
When the user switches tabs, I always want the user to be directed to the Root View Controller for that particular Navigation Controller, and not the most recently visited View Controller (which is the default behavior).
I understand that to do so, I need to call popToRootViewControllerAnimated when a Tab is pressed as discussed here and here, but I can't figure out how to do that within the storyboard. How can I do this without scrapping the storyboard and starting over?
Thanks!
There are more than one solutions to your problem (its a matter of design pattern decision). Some of them could be:
Subclass UITabBarController and set it as the custom class of your tabbar in your storyboard (also connect the delegate to your object in order to be handled) and override the -tabBarController:didSelectViewController: delegate method
Pop to the root by calling -popToRootViewControllerAnimated from the viewWillDisappear event of every view that you want this behavior implemented
You can create your own TabBarController, implement a method that instantiate your view controllers
-(UIViewController*) viewControllerWithTabTitle:(NSString*) title
viewController(NSString *)viewController {
UIViewController* returnViewController = [self.storyboard
instantiateViewControllerWithIdentifier:viewController];
return returnViewController;
}
Then in the viewDidLoad method you create the array with the view controllers, that in your case would be the NavigationController's identifier that you set on the InterfaceBuilder.
- (void)viewDidLoad {
self.viewControllers=
[NSArray arrayWithObjects:
[self viewControllerWithTabTitle:#"Option 1" viewController:#"viewController1"],
[self viewControllerWithTabTitle:#"Option 2" viewController:#"viewController2"],
[self viewControllerWithTabTitle:#"Option 3" viewController:#"viewController3"],
[self viewControllerWithTabTitle:#"Option 4" viewController:#"viewController4"],
[self viewControllerWithTabTitle:#"Option 5" viewController:#"viewController5"], nil];
}

XCode TabBar app - multiple views?

I have been working to create an app with tabs at the bottom, but with the ability to switch views with my own links on the nib's that the tabBar app displays.
I have been trying to find an example of this but xcode 4.2 (whether on ios5.0 or earlier) does not create a mainwindow.xib, so i have had to find a way to create this programmataiically as follows:
#import "AppDelegate.h"
#import "HomeViewController.h"
#import "ViewListViewController.h"
#import "ShareViewController.h"
#import "FriendsViewController.h"
#import "SettingsViewController.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize tabBarController = _tabBarController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *homeViewController = [[HomeViewController alloc] initWithNibName:#"HomeViewController" bundle:nil];
UIViewController *viewListViewController = [[ViewListViewController alloc] initWithNibName:#"ViewListViewController" bundle:nil];
UIViewController *shareViewController = [[ShareViewController alloc] initWithNibName:#"ShareViewController" bundle:nil];
UIViewController *friendsViewController = [[FriendsViewController alloc] initWithNibName:#"FriendsViewController" bundle:nil];
UIViewController *settingsViewController = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
self.tabBarController = [[UITabBarController alloc] init];
[self.tabBarController setDelegate:self];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:homeViewController, viewListViewController, shareViewController, friendsViewController, settingsViewController, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
This code in my AppDelegate.m works fine and i can switch between the tabs perfectly. The issue I am having is that I will be adding graphics to the pages and using them as buttons to switch between views for adding/editing/deleting data from a database (separate issue I will have to learn to do next).
Most examples i have found start the app with either a tabBar, or a uiNavigation with UIViews to switch between. I have yet to find an example that will clearly show how to do what I am looking to do. Is my approach wrong to create the tabBar application as my base template for this, or can this be done? Each tab may have multiple views that perform functions, but I need to be able to create and switch between them within the tabBar framework.
thanks in advance,
Silver Tiger
-UPDATE:-
AFter reading up a bit I am now thinking that aUINavigationController is not what I am looking for. What I need is a way for a custom button that I create to allow me to switch views, as the buttons I will be using in my content will be either graphics or transparent on top of a graphic background. Is it possible to use custom buttons to push new views while still keeping the tabBar visible at all times? My structure would be as below
Home
Add
Edit
delete
ViewList - Single page to view list
Share - Single page to send emails / invites
Friends
Add
Edit
Delete
Settings - Single page for app settings/preferences
so essentially i'd only really have 2 of the tabs where i would be pushing new views but the UINavigationController doesn't seem to fit the method i am using since i am not using a single bar up top to switch views.
Both UINavigationController and UITabBarController are controllers of view controllers. In this function, they work the same way. But there are some differences. Use this as a guide:
UINavigationController: Here you usually have a navigation bar at the top. You "push" other view controllers onto a "stack" and the navigation controller takes care of all the buttons on top to go back and forth as well as the animations, etc. Often, but not always, this is implemented with table views.
UITabBarController: Here you have the tab bar at the bottom at all times, so this should only make sense if there are things the user would typically have to access regardless of where she is in the view hierarchy. Look at the Alarm Clock app for a typical example.
Combination: If you want to combine the two, you start with the tab bar controller. You can then assign separate navigation controllers to one or more tab bar items. The navigation controllers in turn manage their view controllers. Make sure your UI does not get too cluttered with navigation controls at the top and bottom of the screen. Look at the iTunes App for a typical example.
BTW, you can always make these controls disappear, if one view needs more space (e.g. in the iPod app the tab bar gets replaced by a toolbar when going to "Now Playing").

Navigate from one view to another using UIButton

I have an application with 2 views . In the first one I have a button which when I clicked the user should go to the second view. I tried what is explained before here from Karoley , but it does not work . When I click the button nothing happened?
Here is the code of my action :
-(IBAction)gotoSecondPage:(id) sender{
NSLog(#"In gotoSecondPage");
LeoActionViewController *aSecondPageController =
[[LeoActionViewController alloc]
initWithNibName:#"LeoActionViewController"
bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:aSecondPageController animated:YES];
}
LeoActionViewCOntroller is a controler for a second view.
It just do not switch to a second view. I do not know why
I put code your problem this will help you. First of all, you declare method and open .xib file and then connect to that button with selected touchupinside connection.
In the .h file:
- (IBAction)gotoSecondPage:(id) sender;
In the .m file:
- (IBAction)gotoSecondPage:(id) sender
{
NSLog(#"In gotoSecondPage");
LeoActionViewController *aSecondPageController =
[[LeoActionViewController alloc]
initWithNibName:#"LeoActionViewController"
bundle:nil];
[self.navigationController pushViewController:aSecondPageController animated:YES];
[aSecondPageController release];
}
I'm not sure in what capacity you want to switch views.
What immediately comes to mind is that you want a Navigation Controller. This is an object that lets you put view controllers on a stack and push and pop them to show and hide them. It creates a navigation pathway through your app and is easy to use. It also facilitates the 'standard' navigation bar which is found in many iphone apps.
If you just want to change one view for another view you can do many things including hiding and showing different views using setHidden:(bool)hidden. Otherwise you can use addSubview:(UIView *)view and removeFromSuperview to add and remove views completely from the superview.

How to optimize performance in view controller navigation with UISegmentedControl and UITabBarController

On a project I'm working on, the design decision was to use a UISegmentControl at the top, with a UITabBarController on the bottom. The UISegmentControl has 3 choices for 3 different views. Currently, my coworker has added all 3 views to an NSArray when that particular tab is selected, and then based on the UISegmentControl, the view selected gets unhidden, and the other two are hidden. It seems to not follow Apple's guidelines of lazy loading and seems expensive since 3 viewDidLoads (where queries are made to a database) are getting all loaded at once. There is some lag because of it when the tab is selected for the first time, loading all 3 viewControllers at once.
Is there a better way to do this? I saw a simple example with just two viewControllers, and a button that would switch between the two views. That makes sense to me since you always know what your previous view was, and you can remove that view from the superview, present your new one, release your old one. But with 3 choices, I do not know how to keep track of my view hierarchy (since I could be on segment 0, showing view 0, and then go to segment 2, showing view 2). I am not sure how to check for the last view that was shown, and even if that's the best method. I'm thinking that if there is a better option to keep track of this, but still using the segment control, might as well do it now before the project gets more complex. Thanks!
I would suggest creating a root view controller whose job it is to manage the segment control and load the proper VC depending on which button in the segmented control is selected. The root VC's view would have a subView where the segmented control's VC views are inserted. Something like:
- (void)segmentAction:(id)sender
{
NSParameterAssert([sender isKindOfClass: [UISegmentedControl class]]);
switch ([sender selectedSegmentIndex]) {
case 0:
MYViewController1 *vc = [[MyViewController1 alloc] init];
self.segmentVC = vc;
self.segmentSubvew = vc.view;
[vc release];
break;
}
}
One thing people tend to get hung up on is that there needs to be only 1 VC per screenfull of content -- while that was originally what was recommended by Apple, they have since changed this recommendation. So, loading your segment specific VCs inside the SegmentManagerVC is perfectly acceptable.
You could further tweak this design for performance. For example, you could initially load the VC for the default selected segment and then lazy load the other two so they are already available when a different segment is selected. If you take this approach, though, be sure to hook up -didReceiveMemoryWarning to release the two VCs that aren't currently being viewed.
You could push/pop views onto the UINavigationControler stack. This would also support a "back" button if you wanted it.
[self.navigationController pushViewController:self.myVC animated:YES];
Link a method up to the SegmentedControl that pushes the appropriate ViewController when the corresponding segment is selected. The VC with your segmented control inside of it would need a reference to each segment's corresponding VC. viewDidLoad() will only be called once, and only when the view is pushed onto the navigation stack for the first time.
When you change views or want to go "back", you can pop the VC off the stack:
[self.navigationController popViewControllerAnimated:YES];
Is this the type of functionality which you were looking for?
Edit for Clarity
UIViewController References:
Each view will need a reference to the other two view's ViewControllers. This can be done like this: (assume that we are in "View1", and we also have "View2" and "View3":
View2Controller v2Controller = [[View2Controller alloc] initWithNibName:#"View2" bundle:nil];
View3Controller v2Controller = [[View3Controller alloc] initWithNibName:#"View3" bundle:nil];
The reference to self.navigationController should be declared in your app's delegate as:
UINavigationController* navigationController;
It can be initialized as:
[navigationController initWithRootViewController: rootViewController];
The RootViewController
rootViewController is the UIViewController that corresponds to your application's root view (whatever loads on startup). It is declared in the delegate as:
RootViewController* rootViewController;
And initialized as:
rootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];

iPhone - UIButton to select tab in different view

Fairly new to iPhone app development, so this might be really obvious (if so, apologies in advance!)
I'm building an app which has a tab bar. However, when the app first runs and 'launch screen' is shown with 3 UIButtons - each of these buttons points at a view of one of the tabs. What I need to do is:
Close the existing view
Open the selected view
Set the highlighted tab accordingly
This sounds like it should be quite easy, but a few hours of Googling has found nothing!
Thanks for your help,
Kev
Additional:
Sorry - I am using a tabBarController... But instead of immediately launching the tab bar views I'm using the code below to launch the home menu instead.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
homeViewController *splashView = [[homeViewController alloc] initWithNibName:#"homeView" bundle:nil];
[window addSubview:splashView.view];
// [window addSubview:tabBarController.view];
[window makeKeyAndVisible];
return YES;
}
On the home menu there are UIButtons which need to link to individual tabs... Hope this clarifies...
Cheers!
Oh. Then it gets a bit more complex. What you want to do is basically this:
Add a method to your AppDelegate - (void)showTabBarWithSelectedTab:(NSUInteger)tabIndex. In this method, use tabBarController.selectedIndex to select the correct index, then remove homeViewController's view from the window and add tabBarController's view instead.
In homeViewController, have actions for the buttons that calls the newly created AppDelegate method with the correct tab index.
Generally I would say that this adds a bit too much logic to the AppDelegate. Ideally you'd implement this in a new view controller, surrounding and managing both homeViewController and tabBarController. However, having a UITabbarController inside of another view controller isn't officially supported - although you can get it to work anyway.
it's a bit hard to fully understand your question, but it sounds like you should be using UITabBarController instead of the stand-alone view UITabbar. This is essential reading! Good luck