UITableView iPhone Nested Sections

For the acani iPhone app, I would like to display groups (based on interests) in a UITableView . I would like to sort the groups taxonomically, for example:

  • Sport
    • Bat-and-ball
      • Baseball
      • softball
      • Cricket
    • Hockey
      • Field hockey
      • Ice hockey
      • Hockey scooter
  • Engineering
    • Electrical Engineering
    • Biochemical engineering

How do I organize this on a UITableView ?

I think that there must be a UITableView root that will have Sports and Engineering sections, and Bat-and-ball and Hockey cells will be in the Sports section, and electrical and biochemical engineering cells will be in the Technics section.

Then the Bat-and-ball should have its own UITableView , which should have Baseball, Softball, and Cricket cells.

Does this sound like a good way to organize the user interface?

Do you have any sample code or links to sample Xcode code for the user interface? There should be an Xcode example project that does something like this. Perhaps a periodic table of project elements or Core Data Books?

Thanks!

Matt

+7
user-interface ios iphone uitableview
source share
2 answers

Did you understand. A UITableView really not designed to display more than two levels of the hierarchy in the form of sections and rows. If you want to show more than two levels, the β€œsweep” approach is used in most (all?) IOS apps, where row tapping represents another UITableView in the navigation stack. (How do you say.)

There are many Apple code projects that use this design pattern.

Edit: Just checked and DrillDownSave is a good example, since SimpleDrillDown .

+6
source share

The trick to have nested partitions must have two kinds of rows in the table view. One for representing the second level of partitions, and another for representing ordinary rows in a table view. Say you have a two-level array (e.g. partitions) to represent elements in a table view.

Then the total number of partitions that we have is simply the number of top-level partitions. The number of rows in each top-level section will be the number of subsections + the number of rows in each subsection.

 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {    return self.sections.count; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {    NSArray *sectionItems = self.sections[(NSUInteger) section];    NSUInteger numberOfRows = sectionItems.count; // For second level section headers    for (NSArray *rowItems  in sectionItems) {        numberOfRows += rowItems.count; // For actual table rows    }    return numberOfRows; } 

Now we only need to think about how to create rows to represent the table. Set up two prototypes in the storyboard with different reuse identifiers, one for the section heading and the other for the row element, and just create the correct one based on the requested index in the data source method.

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {    NSMutableArray *sectionItems = self.sections[(NSUInteger) indexPath.section];    NSMutableArray *sectionHeaders = self.sectionHeaders[(NSUInteger) indexPath.section];    NSIndexPath *itemAndSubsectionIndex = [self computeItemAndSubsectionIndexForIndexPath:indexPath];    NSUInteger subsectionIndex = (NSUInteger) itemAndSubsectionIndex.section;    NSInteger itemIndex = itemAndSubsectionIndex.row;    if (itemIndex < 0) {        // Section header        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SECTION_HEADER_CELL" forIndexPath:indexPath];        cell.textLabel.text = sectionHeaders[subsectionIndex];        return cell;    } else {        // Row Item        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ROW_CONTENT_CELL" forIndexPath:indexPath];        cell.textLabel.text = sectionItems[subsectionIndex][itemIndex];        return cell;    } } - (NSIndexPath *)computeItemAndSubsectionIndexForIndexPath:(NSIndexPath *)indexPath {    NSMutableArray *sectionItems = self.sections[(NSUInteger) indexPath.section];    NSInteger itemIndex = indexPath.row;    NSUInteger subsectionIndex = 0;    for (NSUInteger i = 0; i < sectionItems.count; ++i) {        // First row for each section item is header        --itemIndex;        // Check if the item index is within this subsection items        NSArray *subsectionItems = sectionItems[i];        if (itemIndex < (NSInteger) subsectionItems.count) {            subsectionIndex = i;            break;        } else {            itemIndex -= subsectionItems.count;        }    }    return [NSIndexPath indexPathForRow:itemIndex inSection:subsectionIndex]; } 

Here is a detailed post on how to do this.

+4
source share

All Articles