1

I am trying to add section titles to my UITableView. I am able to create the sections and count the number of elements in each section properly, but when I call my cellForRowAtIndexPath method, the table repeats the data in both sections.

Here is where I prep the UITableView Section Stuff:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    int sections = 0;
    if (sectionOneCount>0) {
        sections++;
    }

    if (sectionTwoCount>0) {
        sections++;
    }
    return sections;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section==0) {
        return sectionOneCount;
    }
    else {
        return sectionTwoCount;
    }
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    if(section == 0) {
        return @"Section One Title";
    }
    else {
        return @"Section Two Title";
    }
}

Here is my cellForRowAtIndexPath method:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"MainCell";

    ProfileTableViewCell *cell = [mainTableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[ProfileTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    cell.label1.text = [[items objectAtIndex:indexPath.row] valueForKey:@"label1"];
    cell.label2.text = [[items objectAtIndex:indexPath.row] valueForKey:@"label2"];

    return cell;
}

Any ideas on what I'm doing wrong here? Thanks!

P.S. Here is some sample data that I am working with. I only have two possible sections, one for each type (in this case, red and blue). I have one main array called items (as you can see in my cellForRowAtIndexPath methods).

{
    "parentArray": {
        "id": 5,
        "items": [
            {
                "type": "red",
                "title": "RedItem1"
            },
            {
                "type": "red",
                "title": "RedItem2"
            },
            {
                "type": "blue",
                "title": "BlueItem1"
            },
            {
                "type": "blue",
                "title": "BlueItem2"
            },
            {
                "type": "blue",
                "title": "BlueItem3"
            }
        ]
    }
}
Brandon
  • 1,701
  • 3
  • 16
  • 26
  • you need to utilize `indexPath.section` in an `if-else` or `switch` block to perform different logic for different sections. check similar question: [UITableView, how do I know what Section during cellForRowAtIndexPath?](http://stackoverflow.com/questions/1676394/uitableview-how-do-i-know-what-section-during-cellforrowatindexpath) – staticVoidMan Sep 14 '14 at 09:51
  • Thanks, I've been researching this a while and none of the answers I've seen worked with my code thus far. I'll keep on looking. Thanks! – Brandon Sep 14 '14 at 09:54
  • Also, even if i do use an if-else statement, which is what I tried originally, all my data is stored in one array. So I'm not sure how that is supposed to be handled. – Brandon Sep 14 '14 at 09:56
  • hm... ok, so... how do you know which object in the array is for which section? rather, what were you going for? cuz an array of N dictionaries or N arrays could hold values for N possible sections – staticVoidMan Sep 14 '14 at 09:58
  • They're coming out in order. So all of the ones for section 1 come out first, and I have a global integer that increments. Then all of the results for section 2 come out, and I have another global int. Then I include those two integers in my numberOfRowsInSection method. – Brandon Sep 14 '14 at 10:00
  • There is a maximum of two sections, because there are only two types that I'm dealing with. – Brandon Sep 14 '14 at 10:01
  • ok, so give me example data and i think i can show you two ways to handle this – staticVoidMan Sep 14 '14 at 10:02
  • one last thing... are you using a storyboard? – staticVoidMan Sep 14 '14 at 10:10
  • also, how are you calculating `sectionOneCount`/`sectionTwoCount`? I am assuming, as per the example, that you are getting proper values of `sectionOneCount == 2` and `sectionTwoCount == 3`. will this be correct? – staticVoidMan Sep 14 '14 at 10:13
  • Yep, I am. Everything seems to be working, but these rows are just repeating. I've just seen this: http://stackoverflow.com/a/18912120/2905222 Im gonna give this a shot – Brandon Sep 14 '14 at 10:14
  • Yes, the sectionCounts are coming out properly. – Brandon Sep 14 '14 at 10:14

1 Answers1

4

To continue using your logic...

Assuming your sectionOneCount and sectionTwoCount are proper and in the proper order, you can use sectionOneCount as an offset for populating section 2's contents.

Example:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"MainCell";

    ProfileTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if(indexPath.section == 0) {
        cell.label1.text = items[indexPath.row][@"label1"];
        cell.label2.text = items[indexPath.row][@"label2"];
    }
    else if (indexPath.section == 1) {
        cell.label1.text = items[indexPath.row + sectionOneCount][@"label1"];
        cell.label2.text = items[indexPath.row + sectionOneCount][@"label2"];
    }

    return  cell;
}

PS: When using storyboard, you don't need the if (cell == nil) block


Alternatively...

Suppose your items looked like

{
  "items": [// array of sections
    [//array of section 1 items
      {
        "type": "red",
        "title": "redItem1"
      },
      {
        "type": "red",
        "title": "redItem2"
      }
    ],
    [// array of section 2 items
      {
        "type": "blue",
        "title": "blueItem1"
      },
      {
        "type": "blue",
        "title": "blueItem2"
      },
      {
        "type": "blue",
        "title": "blueItem3"
      }
    ]
  ]
}

Basically:

{
  "items": [//array of 2 things
    [ /*array of all redItems*/ ],
    [ /*array of all blueItems*/ ]
  ]
}

This would be:

  1. Scalable, you could easily just add a new greenItems array and more
  2. Remove any dependency on the sectionCount variables
  3. Order of the inner color items wouldn't matter

And... your main delegate methods would simply be:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return items.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [items[section]].count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"MainCell";

    UITableView *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    //no need for if-else anymore as the following is dynamic enough

    cell.label1.text = items[indexPath.section][indexPath.row][@"label1"];
    cell.label2.text = items[indexPath.section][indexPath.row][@"label2"];

    return  cell;
}

PS: This code wouldn't need to be touched even if you updated the datasource with more sections.

staticVoidMan
  • 19,275
  • 6
  • 69
  • 98
  • @Brandon : my pleasure :) but i would recommend you to create a better structure for your datasource so you need not bother about manually calculating the `sectionCount`s – staticVoidMan Sep 14 '14 at 10:24
  • Got it, ill take a look at making that better. Appreciate your help!! – Brandon Sep 14 '14 at 10:27