views:

335

answers:

1

I've been working on an iPhone application in XCode and Interface Builder of the Tab Bar project type. After getting a table view of topics (business sectors) working fine I realized that I would need to add a Navigation Control to allow the user to drill into a subtopics (subsectors) table.

As a green Objective-C developer, that was confusing, but I managed to get it working by reading various documentation trying out a few different IB options. My current setup is a Tab Bar Controller with Tab 1 as a Navigation Controller and Tab 2 a plain view with a Table View placed into it. The wiring works: I can log when table rows are selected and I'm ready to push a new View Controller onto the stack so that I can display the subtopics Table View.

My problem: For some reason the first tab's Table View is a delegate and dataSource of the second tab. It doesn't make sense to me and I can't figure out why that's the only setup that works. I am having other problems that I believe are caused by the goofy wiring.

alt text

Here is the wiring:

  • Navigation Controller (Sectors) is a delegate of Tab Bar
    • Navigation Bar is a delegate of Navigation Controller (Sectors)
    • View Contoller (Sectors) has a view of Table View
    • Table View (in Navigation Controller (Sectors)) is a delegate of First View Controller (Companies)
    • Table View (in Navigation Controller (Sectors)) is a dataSource outlet of First View Controller (Companies)
  • First View Controller (Companies)
    • First View Contoller (Sectors) has a view of Table View
    • Table View (in First View Controller (Companies)) is not hooked up to a dataSource outlet and is not a delegate

When I click the tab buttons and look at the Inspector I see that the first tab is correctly hooked up to my MainWindow.xib and the second tab has selected a nib called SecondView.xib. It's in the File's Owner of MainWindow.xib where I inherit UITableViewDataSource and UITableViewDelegate (and also UITabBarControllerDelegate) in the .h, and in the .m where I implement the delegate methods.

Why does this setup only work when the Table View in my first tab (View Controller (Sectors)) is a delegate and dataSource of the second tab? I'm confused: why wouldn't it need to be hooked up to the Navigation Controller-enabled tab in which the Table View is seen (Navigation Controller (Sectors))? The Table View seen on the second tab has neither dataSource and is not a delegate.

alt text alt text

I'm having trouble getting a pushViewController to fire (self.navigationController is not nil but the new View Controller still doesn't load) and I suspect that I need to work out this IB wiring issue before I can troubleshoot why the Nav Controller won't push a new View Controller onto the stack.

if(nil == self.navigationController) {
    NSLog(@"self.navigationController is nil.");
} else {
    NSLog(@"self.navigationController is not nil.");
    SectorList *subsectorViewController = [[SectorList alloc] initWithNibName:@"SectorList" bundle:nil];
    subsectorViewController.title = @"Subsectors";
    [[self navigationController] pushViewController:subsectorViewController animated:YES];
    [subsectorViewController release];
}
A: 

The first thing that jumps out at me is that the view controller for your Sectors tab is a UIViewController, instead of a UITableViewController. You should just delete that whole view controller and drag a UITableViewController from your library in IB and drop it on your UINavigationController. It will come with a UITableView already hooked up as its view, with the UITableViewController already set as the dataSource and delegate for that tableView.

Once you have a UITableViewController in your NIB, you should then change its class name in the inspector to the name of a UITableViewController subclass that you've implemented in code.

One other thing: You have the dataSource and delegate relationships backwards when you state that your table view "is a dataSource," and "is a delegate". Just to clarify:

  • a tableView HAS a dataSource property, which points to an object that implements the UITableViewDataSource protocol (usually a UITableViewController subclass instance).
  • a tableView HAS a delegate property, which points to an object that implements the UITableViewDelegate protocol (usually the same UITableViewController subclass instance).
  • The UITableViewController class implements both the UITableViewDataSource and UITableViewDelegate protocols. When properly configured, your custom UITableViewController subclass IS the dataSource and delegate of its tableView.
cduhn