【问题标题】:How to hide a section in UITableView?如何在 UITableView 中隐藏一个部分?
【发布时间】:2010-11-06 20:49:29
【问题描述】:

表格中有一些部分不包含任何数据,并希望隐藏该部分。

如何做到这一点?

【问题讨论】:

    标签: iphone iphone-sdk-3.0


    【解决方案1】:

    要隐藏一个部分,即使在表格视图的中间,您也需要以下所有内容

    #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
    

    如果你遗漏了 titleFor/headerFor... 你会得到一些空行
    如果您遗漏了 heightFor... 标题/页脚标题文本仍将出现

    【讨论】:

    • 这仍然会为空白部分留出一点空间。在 splitviewcontroller 中并排放置 2 个表格非常容易查看。
    【解决方案2】:

    我不同意蒂姆的观点。我们有一种方法可以从代码中的任何位置访问表的任何部分/行并更改其 .hidden 属性(以及所有其他属性)。

    这是我通常使用的方式:

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:2];
    [self.SeymourCakesTableView cellForRowAtIndexPath:indexPath].hidden = YES;
    

    【讨论】:

    • 它可以工作,但问题是它下面的单元格没有向上移动。在我的情况下,单元格位于底部表格中,解决方案很好。
    • 我没有注意到这样的问题。有时间我会看看的。感谢您指出问题。
    【解决方案3】:

    对于静态表格的情况,即表格部分和单元格在 Storyboard 中配置。以下是我根据条件隐藏指定部分的策略。

    第一步:实现UITableViewDelegate中定义的两个func - heightForRowAt - heightForHeaderInSection

    例如,这里是 swift 代码:

    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
    }
    

    第二步:定义一个函数来设置隐藏特定部分的单元格并从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()
    }
    

    如果你需要重新加载tableview,你可能需要再次调用setSectionVisible()

    我认为这种策略可能适用于来自 DataSource 的动态数据。通过这种方式,您可以控制何时使特定部分可见或隐藏。

    【讨论】:

      【解决方案4】:

      如果您返回 0 作为部分的高度,Apple API 将忽略它。所以只返回一个大于 0 的小值。

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

      还为标题实现视图,并为您不想显示的部分返回 nil。

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

      【讨论】:

        【解决方案5】:

        试试这样:-

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

        【讨论】:

          【解决方案6】:

          您可以将特定的节行高度设置为 0。此外,如果需要,还可以使用节标题。数据源仍然存在,只是没有显示出来。

          部分行

          - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
          {
              if (indexPath.section == 0) {
                  if (_shouldHidden) {
                      return 0.0;
                  }
                  else {
                      return 55.0;
                  }
              }
              else {
                  return 55.0;
              }
          }
          

          【讨论】:

          • 如果部分有页眉和页脚怎么办?我们会覆盖另外 4 个方法来隐藏它吗?太多不必要的工作,但仍然没有适当的方法来实现这种混乱的解决方案..
          【解决方案7】:

          确实,0 不是页眉和页脚的有效高度。但是,高度是 CGFloat 值。您可以为部分页眉和页脚的高度指定一个非常小的数字(我使用了 0.1)。

          有点小技巧,但确实有效。

          【讨论】:

          • 太棒了!这是分组表视图的解决方案,适用于 iOS 6。
          • 小数也可以使用预定义的 CGFLOAT_MIN
          【解决方案8】:

          实际上,您可以“隐藏”一个部分。如果您想使用与内置联系人应用程序类似的行为,其中部分被隐藏但仍列在右侧的索引中,您可以执行以下操作:

          实现UITableViewDataSource协议:

          • sectionIndexTitlesForTableView 方法中返回所有部分名称(甚至是隐藏的部分)。

          • 对于每个空部分,从 titleForHeaderInSection 方法返回 nil

          • 对于每个空部分,为 numberOfRowsInSection 方法返回 0

          我发现这比删除部分效果更好,因为用户具有一致的索引导航。

          【讨论】:

          • 对我不起作用 - '隐藏' 部分仍然占据垂直空间,当它们中有一些时非常明显。太糟糕了,因为这是一个优雅的解决方案!
          • 请参阅stackoverflow.com/questions/2495936/… 以摆脱默认的页眉/页脚间距。
          • 这非常适合带有标准标题的普通表格 - 没有间距问题。
          • 这就是您要寻找的答案! :)
          • 我在显示/隐藏单元格方面做了很多实验,我也发现这是最好的解决方案。
          【解决方案9】:

          您还可以返回包含来自 numberofSectionsInTableView: 方法和使用 switch(indexPath.section) 您让空记录“通过”到下一个开关,例如:

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

          我为此苦苦挣扎了一段时间,因为我不得不在分组表中间省略部分。尝试将单元格、页眉和页脚高度设置为 0.0,但这不起作用。由于调用的方法取决于所选行,因此不能只删除某些部分。如果有多个子例程调用,这将是一个巨大的 if..else if...else if。 很高兴我想到了旧的 switch 方法,也许它对你也有帮助:-)

          【讨论】:

          • 如果第一条记录没有数据,而第二条记录有,会发生什么? Section==1 将通过案例 1 并返回案例 2 单元格。但是 Section==2 不会知道案例 1 失败,并且在您希望它返回案例 3 单元格时也会返回案例 2 单元格。
          【解决方案10】:

          您可以将该部分中的行数设置为 0。但是,它会在原来的位置留下一个明显的空白区域。

          【讨论】:

            【解决方案11】:

            您不能像这样“隐藏”一个部分,但您可以使用deleteSections:withRowAnimation: 方法从表格视图中“删除”它。这将使用可选动画将其从视图中移除,而不会影响您的支持数据。 (但是,无论如何,您都应该更新数据,以免该部分再次出现。)

            更多信息:UITableView class reference

            【讨论】:

            • 我用过这个:[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:nil];,但我收到这条消息:'无效更新:无效的节数。更新后表视图中包含的节数(3)必须等于更新前表视图中包含的节数(3),加上或减去插入或删除的节数(0插入,1已删除)。有什么想法吗?
            • @Claus:这个答案已经很老了。你可以考虑asking a new question。不过,简而言之,您似乎需要更新从 -numberOfSectionsInTableView: 数据源方法返回的值。该错误表明您从三个部分开始,删除一个,然后声称您还剩下三个部分。
            • 谢谢!我找到了一种更简单的方法,将部分的行数设置为 0 并删除部分标题视图。
            • @Claus 怎么办?
            【解决方案12】:

            您可能需要从支持您的表格的数据中删除该部分本身。我不认为有任何东西可以让你隐藏一个部分。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-11-17
              • 1970-01-01
              • 1970-01-01
              • 2020-10-21
              • 2017-01-24
              • 2015-11-05
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多