Hide sections of a Static TableView
Asked Answered
C

6

25

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!

Cremate answered 20/7, 2013 at 11:41 Comment(2)
What is the purpose of trying to make a static table be dynamic? That's what dynamic tables are for.Twannatwattle
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!Cremate
C
47
- (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 
    }    
}
Cremate answered 20/7, 2013 at 16:29 Comment(2)
If the table is a group table then it is better to return 0.1 for header/footer height. Returning 0 causes the UITableView to still have a gap where the section should be.Insula
that's a good idea, usually i return 1 but 0.1 is even better!! =)Cremate
H
19

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.

Hem answered 15/3, 2016 at 5:9 Comment(5)
I created a subclass of UITableViewController called DynamicUITableViewController. It allows hiding of sections/rows w/o having to implement all of this code in your TableViewControllers. Here's the github repo: (github.com/tkeithblack/DynamicUITableViewController)Hem
I just discovered that rather than returning -1 when you don't wish to shrink a row or header if you call super.tableView(...) this will then honor the Custom Row Height that is set in the storyboard. I've edited the example above and my github entry to reflect this change.Hem
In table​View(_:​will​Display​Header​View:​for​Section:​) and table​View(_:​will​Display​Footer​View:​for​Section:​) you can simply do view.isHidden = true instead of casting and making the UILabel transparent.Yerkovich
Gary, thanks for the suggestion. I tried this and though it did hide the unwanted header text, it also hid some unrelated headers I didn't want hidden. My guess is that this may have to do with the reusable nature of cells. Why this is the case for isHidden and not textColor=clear I'm not sure, but perhaps the text color is reset by the system prior to each call to draw a header and isHidden is not.Hem
trying to implement this , where do I use shouldHideSection(section: x)Stansbury
B
4

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)
}
Burck answered 29/12, 2016 at 23:51 Comment(0)
B
2

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;
}
Belie answered 16/7, 2015 at 17:20 Comment(0)
D
1

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;
}
Deraign answered 5/4, 2015 at 1:21 Comment(0)
R
0

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.

Rhines answered 3/5, 2016 at 15:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.