3

I need to create a grouped uitableview that includes some sections and possibly different cell types in each sections.

I am trying to create something like old foursquare app, user page (includes 'leaderboard', 'friend suggestions', 'friends', 'stats', 'most explored categories' ... sections).

I am fairly new to ios programming, so that view may not be a grouped uitableview.

What I especially stuck is creating different cells for sections, and finding out which cells are clicked.

My data source will be 2 different NSArray* that consists of different data types, that's why I need different custom cells.

tackleberry
  • 1,003
  • 2
  • 12
  • 16

2 Answers2

6

Since you have two different sets of data and you need to display both in different sections, you have to split the data source methods into two.

Basically, choose which dataset you want to be first and off you go.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if(section)return secondArray.count;
    //Essentially, if statements evaluate TRUE and move forward if the inside is 1 or greater (TRUE == 1)
    return firstArray.count;
    //If the first if statement return hits, then the code will never reach this statement which turns this into a lighter if else statement
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(indexPath.section)
    {
        //do stuff with second array and choose cell type x
    }
    else
    {
        //do stuff with first array and choose cell type y
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //Get the cell with: UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if(indexPath.section)
    {
        //perform action for second dataset
    }
    else
    {
        //perform action for first dataset
    }
}

For headers, you can use either of these methods and just keep the same type of styling as above:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
RileyE
  • 10,874
  • 13
  • 63
  • 106
  • 1
    Feel free to ask me about it. – RileyE Jun 25 '12 at 21:43
  • 1
    I think you should clarify that indexPath.section and section in if statements should be compared to 0 and 1. Oh and make "`if(section)return secondArray.count; return firstArray.count;`" `if(section = 0){return firstArray.count} else{return secondArray.count}` – erran Jun 25 '12 at 21:47
  • thanks @RileyE. It's crystal clear now except setting headers for each section. Can you add that info too in your answer please if you know about that? – tackleberry Jun 25 '12 at 21:50
  • thanks @ipwnstuff, helped me to understand section/count thing. – tackleberry Jun 25 '12 at 21:51
  • Does this work better? I'm trying to explain, rather than change. – RileyE Jun 25 '12 at 21:55
  • I understood your code, it's very clear, thanks. The only problem is I don't know where/how to set headers for each sections. Can you add that info too if you have any idea? – tackleberry Jun 25 '12 at 22:03
  • Sorry for the lack of header info. I'll add it in now in case someone else looks for it. – RileyE Jun 25 '12 at 23:51
5

You can create multiple custom subclasses of UITableViewCell, and in the tableView:cellForRowAtIndexPath: method for your UITableViewDataSource, you can use if-statements to determine what type of cell to use.

For example, here's a rough outline of what I might do:

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

    //First, determine what type of object we're showing
    if (indexPath.section == 0) {
         //Create and return this cell.
    } else if (indexPath.section == 1) {
         //Create and return this cell.
    }...
}

Here's how you'd implement numberOfRowsInSection:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

   if (section == 0) {
      return [firstSectionArray count];
   } else if (section == 1) {
      return [secondSectionArray count];
   } ...
}

For didSelectRowAtIndexPath

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
   if (indexPath.section == 0) {
      ObjectSelected *objectSelected = [firstArray objectAtIndex:indexPath.row];

      //Now you've got the object, so push a view controller:
      DetailViewController *dvc = [[DetailViewController alloc] init];
      dvc.objectSelected = objectSelected;
      [self.navigationController pushViewController:dvc];
   } else if (indexPath.section == 1) {
      //Same thing, just call [secondArray objectAtIndex:indexPath.row] instead!
   }
}
bryanjclark
  • 6,247
  • 2
  • 35
  • 68
  • thanks for the answer. Ok it makes sense, but how can I get the item in this method, I have 2 different arrays but this method give just the index? and how can I implement numberOfRowsInSection and didSelectRowAtIndexPath methods by your method? – tackleberry Jun 25 '12 at 20:36
  • I don't think you've made your question very clear. What exactly are you trying to do and what is wrong with this answer? This is exactly what you need to do to create different types of cells. – RileyE Jun 25 '12 at 20:57
  • @RileyE yeah I guess you are right. As I said in my comment this may solve placing different types of cells but I still have no idea how can I understand which cell is being clicked, and how can I pass data to its click action. I hope it is clear now? – tackleberry Jun 25 '12 at 21:00
  • 1
    Yes. That is better. You will get the indexPath in the didSelectRow method and then you just have to perform the same type of check that you did before on the arrays in order to figure out what type it is. – RileyE Jun 25 '12 at 21:02
  • thanks alot @RileyE. One last question if that's not too much. How can I set TableView's data source with 2 different NSArray? – tackleberry Jun 25 '12 at 21:18
  • What are the two different arrays? Are they the two different sections? – RileyE Jun 25 '12 at 21:22
  • yes 2 different NSArray of NSDictionary items for 2 different sections – tackleberry Jun 25 '12 at 21:26
  • I'll post it as an answer if it helps. – RileyE Jun 25 '12 at 21:36
  • Hey @tackleberry, I've updated the entry to show what you can do for the numberOfRowsInSection and didSelectRowAtPath entries. – bryanjclark Jun 26 '12 at 21:25
  • thanks a lot @bryanjclark! I actually got it working with Riley after your answer, but I think this thread (your answer and Riley's) may save some time for ios newbies, just like me. Thanks again – tackleberry Jun 27 '12 at 22:38