Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove sections with no rows from UITableView

I would like to remove section headers from a UITableView if there are no rows for that section.

I'm using UILocalizedIndexedCollation for my section headers. So when I create the headers, I don't necessarily know what sections will have content.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    //return [customerSections count];
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return 1;
    }
    return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    //NSLog(@"Section: %i", section);
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return self.filteredCustomers.count;
    } else {
        return [[self.customerData objectAtIndex:section] count];
    }
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    // The header for the section is the region name -- get this from the region at the section index.

    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return nil;//@"Results";
    }
    return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] objectAtIndex:section];
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    //return [customerSections allKeys];
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return nil;
    }
    return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];
}

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
    return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];
}
like image 996
Bot Avatar asked Mar 08 '12 16:03

Bot


4 Answers

Just wanted to chime in and give my solution to this

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    if ([self.myTableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
        return nil;
    }
    return [[self.collation sectionTitles] objectAtIndex:section];

}

based on this answer

like image 76
owen gerig Avatar answered Nov 18 '22 22:11

owen gerig


I've recently achieved this with this code:

This is the function that returns the title for the section, if there are no rows in that section then don't return a title:

  - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
     if ([self.customerData count] > 0 ) {
             return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] objectAtIndex:section];
        }
    return nil;
}
like image 43
CW0007007 Avatar answered Nov 18 '22 22:11

CW0007007


It's an interesting question, with a number of possible solutions.

Working backwards, numberOfSectionsinTableView and numberOfRowsInSection are what need to be updated in order to display the right number of sections. These are partly dependent on the methods UILocalizedIndexedCollation methods.

(Presumably this happens after some sort of user action (a delete or an insert), so note that in commitEditingStyle you should call [self.tableView reloadData).

I am assuming that customerData is an array, where at each index there is a mutable array that corresponds to a section. When the array at a certain customerData index has no data, you want to remove the section for that index.

The solution then, is to calculate everything manually - determine section information based on lives inside your customerData array. I took a stab at rewriting three of your methods. Good luck!

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return nil;
    }
   NSMutableArray *arrayToFilter = [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];

   //This is the key - recalculate index titles based on what's present in customerData
   for (int i = [self.customerData count] -1; i >=0 ; i--) {
       if (![[self.customerData objectAtIndex:i] count]) {
            [self.arrayToFilter removeObjectAtIndex:i];
       }
   }
   return arrayToFilter;
}

//You need to be calculating your table properties based on the number of objects
//rather of the 'alphabet' being used.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    //return [customerSections count];
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return 1;
    }
    //return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] count];
    int populatedArrayCounter = 0;        
    for (int i = 0; i <[self.customerData count]; i++) {
        if ([[self.customerData objectAtIndex:i] count]) {
            populatedArrayCounter++;
        }
    }
    return populatedArrayCounter;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    //NSLog(@"Section: %i", section);
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return self.filteredCustomers.count;
    } else {
        // Your original line requires changing, because there are customerData array objects with a count of 0, and you don't want any sections like that
        // Thus, pick from the set of populated arrays.
       NSMutableArray populatedArrays = [[NSMutableArray alloc] init];        
       for (int i = 0; i <[self.customerData count]; i++) {
           if ([[self.customerData objectAtIndex:i] count]) {
               [populatedArrays addObject:i];
           }
       }
       return [[populatedArrays objectAtIndex:section] count];;
    }
}
like image 21
Eitan Avatar answered Nov 18 '22 20:11

Eitan


I wanted to share my solution in swift

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    if self.sections[section].isEmpty
    {
        return nil
    }
    else
    {
        return collation.sectionTitles[section]
    }
}
like image 22
syson16 Avatar answered Nov 18 '22 22:11

syson16