24
votes

I've found this tutorial which hides a section of a Static TableView: http://code-ninja.org/blog/2012/02/29/ios-quick-tip-programmatically-hiding-sections-of-a-uitableview-with-static-cells/

It works great but only without modifying it, if I add a section or a row, it works bad. I'm a beginner and I'm not able to modify it, can somebody help me hiding more than one section?

Thank you so much!

6
What is the purpose of trying to make a static table be dynamic? That's what dynamic tables are for. - Timothy Moose
My ideas was to implement it in my, more complicated, app and there I can't convert everything to dynamic, however I've (more or less) solved! - Matte.Car

6 Answers

46
votes
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {            
    if (section == 2 && _hideTableSection) {
        //header height for selected section
        return 0.1; 
    } else {
        //keeps all other Headers unaltered 
        return [super tableView:tableView heightForHeaderInSection:section]; 
    }  
}

-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {        
    if (section == 2 && _hideTableSection) {
        //header height for selected section
        return 0.1; 
    } else {
        // keeps all other footers unaltered
        return [super tableView:tableView heightForFooterInSection:section]; 
    } 
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section == 1) { //Index number of interested section
        if (hideTableSection) {
            return 0; //number of row in section when you click on hide
        } else {
            return 2; //number of row in section when you click on show (if it's higher than rows in Storyboard, app will crash)
        }
    } else {
        return [super tableView:tableView numberOfRowsInSection:section]; //keeps inalterate all other rows 
    }    
}
18
votes

I wanted to share some code that I wrote to solve this problem after digging though lots of answers and bumping into many glitches. This is for xCode 7.2.1. (Code examples in Swift)

My use case was that I wanted to use the ease of storyboard static grouped TableView, but I needed to hide particular sections based on user profiles. To make this work (as described in other posts) I need to hide the headers and footers, the rows in the section AND hide the header/footer text (at least on the top section). I found that if I didn't hide (make transparent) the text then the user could scroll up past the top of the table (under the Navigation Controller) and see text all crammed together.

I wanted to make this easy to modify and didn't want conditions spread all through my code, so I created a single function called shouldHideSection(section: Int) which is the only function I have to change to modify which rows are hidden.

func shouldHideSection(section: Int) -> Bool {
    switch section {
    case 0:  // Hide this section based on condition below
        return user!.isProvider() ? false : true

    case 2:
        return someLogicForHiddingSectionThree() ? false : true

    default:
        return false
    }
}

Now the remainder of the code just calls shouldHideSection().

// Hide Header(s)
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return shouldHideSection(section) ? 0.1 : super.tableView(tableView, heightForHeaderInSection: section)
}

// Hide footer(s)
override func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return shouldHideSection(section) ? 0.1 : super.tableView(tableView, heightForFooterInSection: section)
}

// Hide rows in hidden sections
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return shouldHideSection(indexPath.section) ? 0 : super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}

// Hide header text by making clear
override func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    if shouldHideSection(section) {
        let headerView = view as! UITableViewHeaderFooterView
        headerView.textLabel!.textColor = UIColor.clearColor()
    }
}

// Hide footer text by making clear
override func tableView(tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) {
    if shouldHideSection(section) {
        let footerView = view as! UITableViewHeaderFooterView
        footerView.textLabel!.textColor = UIColor.clearColor()
    }
}

I had to experiment with many different values (returning 0, 0.1, -1, ...) to finally get a satisfactory solution (at least on iOS 9.x).

I hope this is helpful, let me know if you have suggested improvements.

4
votes

For Swift

var hideTableSection = true

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    
    if section == 2 && hideTableSection {
        //header height for selected section
        return 0.1
    }
    
    //keeps all other Headers unaltered 
    return super.tableView(tableView, heightForHeaderInSection: section)
}

override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    
    if section == 2 && hideTableSection {
        //header height for selected section                
        return 0.1
    }
    
    return super.tableView(tableView, heightForFooterInSection: section)
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
    if section == 1 { //Index number of interested section
        if hideTableSection {
            return 0 //number of row in section when you click on hide
        } else {
            return 2 //number of row in section when you click on show (if it's higher than rows in Storyboard, app will crash)
        }
    } else {
        return super.tableView(tableView, numberOfRowsInSection: section) //keeps inalterate all other rows 
    }
}

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

    if section == 2 && hideTableSection {
        return ""
    }

    return super.tableView(tableView, titleForHeaderInSection: section)
}

override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {

    if section == 2 && hideTableSection {
        return ""
    }

    return super.tableView(tableView, titleForFooterInSection: section)
}
2
votes

If you return 0 for the height of the section, Apple API will ignore it. So just return a small value greater than 0.

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  if (section == 0) {
    return 1;
  }

  return 44;
}

Also implement view for header and return nil for the section you don't want to show.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  if (section == 0 && !self.personaCells.count) {
    return nil;
  }

  UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 44)];
  UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 20, headerView.frame.size.width, 20)];
  NSString *headerTitle = @"SAMPLE TITLE";
  headerLabel.text = headerTitle;    
  [headerView addSubview:headerLabel];
  return headerView;
}
1
votes

Set the section value to 0.01, Whatever section you wanted to hide you can try in this way:-

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    CGFloat headerHeight=10.f;
    if (section==0)
    {
        headerHeight=0.01f;
    }
    else
    {
        headerHeight=50.0f;
    }
    return headerHeight;
}
0
votes

if you erase the title of the section header from storyboard, it automatically disappears. By that, I mean not just the title content, but also the space taken by it.