views:

306

answers:

2

Hi there,

I've set up a grouped table on my app, and pushing to new views works fine. Except for one thing. The titles and stack layout are all weird. Here's the breakdown:

  1. I have two sections in my table.
  2. When I tap on the first row in the first section, it takes me to the correct view, but the title of the new view is the name of the first row in the second section of the table.
  3. In turn, the second row in the first section's title is the second row in the second section's title.

If I tap on the second row in the second section of the root view table, the navigation button goes to the second row in the first section of the table.

So here's a diagram of my table:


Table Section 1
Row 1
Row 2
Row 3

Table Section 2
Row A
Row B
Row C


So if I tap on row 3, the title of the pushed view is Row C. The navigation button tells me to go back to Row 3, then eventually ending up at the root view.

Here's my implementation file pushing the views:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    //CSS
    if ([[arryClientSide objectAtIndex:indexPath.row] isEqual:@"CSS"])
    {
        CSSViewController *css = [[CSSViewController alloc] initWithNibName:@"CSSViewController" bundle:nil];
        [css setTitle:@"CSS"];
        [self.navigationController pushViewController:css animated:YES];
    }

    //HTML
    if ([[arryClientSide objectAtIndex:indexPath.row] isEqual:@"HTML"])
    {
        HTMLViewController *html = [[HTMLViewController alloc] initWithNibName:@"HTMLViewController" bundle:nil];
        [html setTitle:@"HTML"];
        [self.navigationController pushViewController:html animated:YES];
    }

    //JS
    if ([[arryClientSide objectAtIndex:indexPath.row] isEqual:@"JavaScript"])
    {
        JSViewController *js = [[JSViewController alloc] initWithNibName:@"JSViewController" bundle:nil];
        [js setTitle:@"JavaScript"];
        [self.navigationController pushViewController:js animated:YES];
    }

    //PHP
    if ([[arryServerSide objectAtIndex:indexPath.row] isEqual:@"PHP"])
    {
        PHPViewController *php = [[PHPViewController alloc] initWithNibName:@"PHPViewController" bundle:nil];
        [php setTitle:@"PHP"];
        [self.navigationController pushViewController:php animated:YES];
    }

    //SQL
    if ([[arryServerSide objectAtIndex:indexPath.row] isEqual:@"SQL"])
    {
        SQLViewController *sql = [[SQLViewController alloc] initWithNibName:@"SQLViewController" bundle:nil];
        [sql setTitle:@"SQL"];
        [self.navigationController pushViewController:sql animated:YES];
    }

& the array feeding the table's data:

- (void)viewDidLoad {
    [super viewDidLoad];


    arryClientSide = [[NSArray alloc] initWithObjects:@"CSS",@"HTML",@"JavaScript",nil];
    arryServerSide = [[NSArray alloc] initWithObjects:@"Objective-C", @"PHP",@"SQL",nil];
    // arryResources = [[NSArray alloc] initWithObjects:@"HTML Colour Codes", @"Useful Resources", @"About",nil];
    self.title = @"Select a Language";
    [super viewDidLoad];

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

Any help would be greatly appreciated.
Jack

+4  A: 

I think you are missing an if statement to determine which section the user tapped on. Remember that NSIndexPath has both a row and a section property. I usually do something like this:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ( indexPath.section == 0 ) {
  // Do something with arryClientSide
}
if ( indexPath.section == 1 ) {
  // Do something with arryServerSide
}

I'm assuming you are using a grouped table.

Cheers, -dan

Daniel Blezek
Awesome, thanks.
Jack Griffiths
A: 

Dan is right, you need to use the indexPath.section variable. It appears the way your code is now, you are actually pushing 2 view controllers since you have a series of individual if statements, after you click "Row 1" the following happens:

isEqual:@"CSS" will return true,

push the css view controller,

then drop down and keep checking (if.. isEqual:@"HTML").. (if.. isEqual:@"JavaScript")

then sure enough (if.. isEqual:@"PHP") will also return true and push the php view controller.

I'm not aware of your entire application but one observation I notice here (besides memory leaks) is you have one view controller/nib dedicated to each language.. if the view controllers have vastly different behaviors/appearances then I guess that's what you have to do, but I would recommend trying to see what the similarities between each one and see if you can't make a single "LanguageViewController", pass in what language its supposed to represent and do initialization/set the properties of the view controller based off that. This might not apply but if it does it would save you a lot of work!

Tom
With regards to the last thing you mentioned, will I just need one nib which will control every language? I created individual nibs when Xcode created them for me when I created a viewcontroller. I then feed the view controller with an array to create a further table. Would I be able to feed the data of each programming language from a plist? And would I then be able to create a navigation controller to control each item of the plist?
Jack Griffiths
Yea this sounds like a situation where you would just make a "LanguageViewController" (and nib), create a custom init function with an extra language string argument then in the init function do something like (the following is psuedo-code of course): if(language equals "CSS") load data from CSS.plist;else if(language equals "HTML") load data from HTML.plist;etc..merely a suggestion though, when in doubt do what makes most sense to you.
Tom
Right, so I would simply amend all the initWithNibName's on my code to the new LanguageViewController nib?
Jack Griffiths
LanguageViewController would replace ALL of the CSS/HTML/PHP/etc view controllers. In LanguageViewController.m create an init function - (id) initWithNibName:(NSString*)nibNameOrNil Language:(NSString*)lang;In that function you would specify which plist the view should get it's data from based on the "lang" argument.And you would call it in didSelectRowAtIndexPath kinda like this:if(indexPath.section == 0) initWithNibName:@"LanguageViewController" lang:[arryClient objectAt:indexPath.row] then do similar but with arryServerSide for section==1
Tom