How to hide a section in UITableView?

前端 未结 12 2181
梦如初夏
梦如初夏 2020-12-05 00:32

There are some section in the table that does not contain any data and would like to hide that section.

How to do this?

相关标签:
12条回答
  • 2020-12-05 01:11

    Actually, you can "hide" a section. If you want to use a similar behaviour to the built-in contacts app, where sections are hidden but still listed in the index on the right you can do the following:

    Implement the UITableViewDataSource protocol:

    • Return all section names (even hidden ones) in - the sectionIndexTitlesForTableView method.

    • For each empty section, return nil from the titleForHeaderInSection method.

    • For each empty section return 0 for the numberOfRowsInSection method.

    I find this works better than deleting sections, because the user has consistent index navigation.

    0 讨论(0)
  • 2020-12-05 01:12

    You can also return the number of records that do contain data from the numberofSectionsInTableView: method and use a switch(indexPath.section) where you let the empty records 'fall through' to the next switch, like:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        switch (indexPath.section) {
            case 0:
                return <header cell>;
                break;
    
            case 1:
                if(firstRecordHasData){
                    return <second cell>;
                    break;
                }
    
            case 2:
                if(secondRecordHasData){
                    return <second cell>;
                    break;
                }
    
            case 3:
                return <some other cell>;
                break;
    
            default:
                return <a regular cell>;
                break;
        }   
    }
    

    I was struggling with this for a while because I had to leave out sections in the middle of a grouped table. Tried with setting cell-, header- and footer heights to 0.0 but that didn't work. Couldn't just delete certain sections because of the called methods depending on the selected row. This was going to be a huge if..else if...else if with multiple callings of subroutines. Glad I thought of the good old switch method, maybe it helps you as well :-)

    0 讨论(0)
  • 2020-12-05 01:13

    For hiding a section, even in the middle of the table view you would need all of the following

    #define DEBUG_SECTION 1
    
    #if ! DEBUG_BUILD
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
    {
        if (section == DEBUG_SECTION)
            return CGFLOAT_MIN;
        return [super tableView:tableView heightForHeaderInSection:section];
    }
    //------------------------------------------------------------------------------
    
    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
    {
        if (section == DEBUG_SECTION)
            return CGFLOAT_MIN;
        return [super tableView:tableView heightForFooterInSection:section];
    }
    //------------------------------------------------------------------------------
    
    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
        if (section == DEBUG_SECTION)
            return nil;
        return [super tableView:tableView titleForHeaderInSection:section];
    }
    //------------------------------------------------------------------------------
    
    - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
    {
        if (section == DEBUG_SECTION)
            return nil;
        return [super tableView:tableView titleForFooterInSection:section];
    }
    //------------------------------------------------------------------------------
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        if (section == DEBUG_SECTION)
            return 0;
        return [super tableView:tableView numberOfRowsInSection:section];
    }
    //------------------------------------------------------------------------------
    #endif // #if ! DEBUG_BUILD
    

    if you left out titleFor/headerFor... you will get some empty rows
    if you left out heightFor... the title/footer header text will still appear

    0 讨论(0)
  • 2020-12-05 01:16

    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;
    }
    
    0 讨论(0)
  • 2020-12-05 01:16

    For the case of static table, that is, the table sections and cells are configured in Storyboard. The following are my strategies to hide a specified section depending conditions.

    Step one: implement two func defined in UITableViewDelegate - heightForRowAt - heightForHeaderInSection

    For example, here are swift codes:

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    {
       // if indexPath contains the specified section AND
       //    the condition for hiding this section is `true`
       //       return CGFloat(0)
       // else 
       //    return super.tableView(tableView, heightForRowAt: indexPath)
    }
    
    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat 
    {
       // similar logic to set header height
    }
    

    Step two: define a func to set cells hidden for specific section and call it from viewWillAppear:

    private func setSectionVisible()
    {
       /*
       if condition for visible is true
          let index = IndexPath(row:..., section:...)
          let cell = self.tableView.cellForRow(at: index)
          cell.isHiden = true
       */
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.setSectionVisible()
    }
    

    In case you need to reload tableview, you may need to call setSectionVisible() again.

    I think this strategy may work for dynamic data from DataSource. In this way, you can control when to make specific section visible or hidden.

    0 讨论(0)
  • 2020-12-05 01:17

    Try like this:-

    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
    {
        CGFloat headerHeight=10.f;
        if (section==0)
        {
            headerHeight=0.01f;
        }
        else
        {
            headerHeight=50.0f;
        }
        return headerHeight;
    }
    
    0 讨论(0)
提交回复
热议问题