views:

188

answers:

1

Here is the setup of my iPhone App:

I have a UITabBarController that has 4 View Controllers (1 UINavigationController & 3 UIViewControllers).

Onload my app is defaulted to the UINavigationController, where there is a grouped UITableView which gives two navigation options, when the user hits the first option the relevant UITableViewController (Contains a list of locations) is pushed onto the stack.

What I would like to happen on screen is to have a UISegmentedControl that has two options, a "List View" (which the user sees by default when the UIViewController gets pushed) ans a "Map View" that will allow the relevant locations to be represented on the map.

I use the follwing code to create the UISegmentedControl on the NavigationBar:

UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:segmentItems];
 [segmentedControl setSelectedSegmentIndex:0];
 [segmentedControl setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
 [segmentedControl setSegmentedControlStyle:UISegmentedControlStyleBar];
 [segmentedControl addTarget:self action:@selector(segmentAction:) forControlEvents:UIControlEventValueChanged];

 [[self navigationItem] setTitleView:segmentedControl];
 [segmentedControl release];

And this is the method that the UISegmented control will call when changed:

- (void) segmentAction:(id)sender
{
 UISegmentedControl *segmentControl = sender;

 if([segmentControl selectedSegmentIndex] == 0)
 {
  NSLog(@"LIST VIEW CHOSEN!");
 }
 else
 {
  NSLog(@"MAP VIEW CHOSEN!");
 }
}

So basically my question is what is the correct/best way to implement what I am trying to achieve, I dont want to push the controller onto the navigation stack, I just want to toggle it in place (possibly with animation). All interfaces are built in IB.

One way i tried to do it, that worked but didn't feel like it was the correct was by creating two separate UIViews in my nib file (One for the List View and one one for the Map view), and then using setView: appropriately.. but then I thought shouldn't each of these views have there own controller and/or own nib?

- (void) segmentAction:(id)sender
{
 UISegmentedControl *segmentControl = sender;

 if([segmentControl selectedSegmentIndex] == 0)
 {
  NSLog(@"LIST VIEW CHOSEN!");
  [self setView:listView]; //Declared as an UIView IBOutlet
 }
 else
 {
  NSLog(@"MAP VIEW CHOSEN!");
  [self setView:mapView]; //Declared as an UIView IBOutlet
 }
}

Some semi related examples I have come across use "removeFromSuperview" and "addSubview" and this has somewhat confued me, i'm relatively new to Cocoa Touch development, so any help getting my head around this would be appreciated.

Thanks

A: 

There are a couple of ways to handle this, if you are simply going between a TableView (that is already on the UINavigationController stack) and a mapview that goes with this SPECIFIC UITableView, you could have the segmentedControl display the mapviewController modally, that is presentModalViewController:. This does have some drawbacks as to functionality, but it could be what you are looking for if the mapview will be relatively simple.

Another way of implementing this, and probably the most robust way, is to have one view controller that handles both the table view and the map view. This is ideal if they have the same data source for certain.

One other way is to have two view controllers, one each for the table view and map view, and literally do pushes and pops on the navigation controller stack in your segmentAction method. Ex:

- (void) segmentAction:(id)sender
{
 UISegmentedControl *segmentControl = sender;

 if([segmentControl selectedSegmentIndex] == 0)
 {
  NSLog(@"LIST VIEW CHOSEN!");
  [self.navigationController popViewControllerAnimated:YES];
[self.navigationController pushViewController:listViewController animated:YES];
 }
 else
 {
  NSLog(@"MAP VIEW CHOSEN!");
   [self.navigationController popViewControllerAnimated:YES];
[self.navigationController pushViewController:mapViewController animated:YES];
 }
}

I would make sure to read the Human Interface Guidelines, as well as the documentation of how view controllers and navigation controllers work.

Jesse Naugher
Jesse,thanks for your quick reply, presenting modally isn't really an option. Maybe the one view controller is the way to go.. which is what I am doing with setView: on the two IBOutlets - just didnt feel right and though that both views should have there own controllers... I dont think the pop/push method would look right for a segmented control, I just want to toggle the views like the Youtube application does for "Most Viewed (Today/Week/All)"... So i guess I was on the right track. Thanks for your comment.