Hide sections of a Static TableView

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)
}

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;
}

- (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 
    }    
}

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.