【问题标题】:How to hide first section header in UITableView (grouped style)如何在 UITableView 中隐藏第一节标题(分组样式)
【发布时间】:2013-10-04 02:03:11
【问题描述】:

由于使用分组样式的表格视图设计在 iOS 7 中发生了很大变化,我想隐藏(或删除)第一节标题。到目前为止,我还没有设法实现它。

稍微简化一下,我的代码如下所示:

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

- (UIView*) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        UIView* view = [[UIView alloc] initWithFrame: CGRectMake(0.0f, 0.0f, 640.0f, 0.0f)];
        return view;
    }
    return nil;
}

- (NSString*) tableView:(UITableView *) tableView titleForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return nil;
    } else {
        // return some string here ...
    }
}

如果我返回 0 的高度,则永远不会使用节索引 0 调用其他两个方法。然而,仍然使用默认高度绘制空的节标题。 (在iOS 6中,这两个方法都被调用了,但是可见的结果是一样的。)

如果我返回不同的值,节标题将获得指定的高度。

如果我返回 0.01,它几乎是正确的。但是,当我在模拟器中打开“颜色未对齐的图像”时,它会标记所有表格视图单元格(这似乎是一个合乎逻辑的结果)。

UITableView: hide header from empty section 问题的答案似乎表明有些人成功地隐藏了节标题。但它可能适用于普通样式(而不是分组样式)。

到目前为止,最好的折衷方案是返回高度 0.5,从而在导航栏下方产生一条较粗的线。但是,如果有人知道如何完全隐藏第一节标题,我将不胜感激。

更新

根据caglar的分析(https://stackoverflow.com/a/19056823/413337),只有在导航控制器中包含表格视图时才会出现问题。

【问题讨论】:

  • 我没有得到那部分 => if(section==0) return view;返回零;即在第一部分返回视图,否则返回 nil?
  • 这个想法是为第一部分返回一个高度为 0 的视图,并为所有其他部分返回 nil 以便表格视图使用它们的默认标题视图. nil 部分很好用;表格视图显示了这些部分的标题。但是第 0 部分的部分无关紧要,因为该方法从未使用 section == 0 调用。
  • 这个答案似乎简短而甜蜜。 stackoverflow.com/a/23955420/3965

标签: ios uitableview ios7


【解决方案1】:

我有一个对我来说似乎相当干净的解决方法。所以我在回答我自己的问题。

由于 0 作为第一节标题的高度不起作用,我返回 1。然后我使用 contentInset 将该高度隐藏在导航栏下方。

目标-C:

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

- (NSString*) tableView:(UITableView *) tableView titleForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return nil;
    } else {
        // return some string here ...
    }
}

- (void) viewDidLoad
{
    [super viewDidLoad];

     self.tableView.contentInset = UIEdgeInsetsMake(-1.0f, 0.0f, 0.0f, 0.0);
}

斯威夫特:

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return section == 0 ? 1.0 : 32
}

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.contentInset = UIEdgeInsets(top: -1, left: 0, bottom: 0, right: 0)
}

【讨论】:

  • 使用 0.1f 的标题高度更适合隐藏它。
  • 我试过使用 0.1f。但结果是绘图不再与像素对齐,导致模糊并降低性能。只需在模拟器中尝试一下:它有一个选项可以突出显示有问题的对齐方式。
  • 实际上,更好的实现(将来不太可能中断)是使用CGFLOAT_MIN 而不是硬编码的值。换句话说,不要return 1.0f0.1f 而是return CGFLOAT_MIN 如果Apple 更改了最小可接受值,那么如果您对返回值进行硬编码,那么您将需要更改代码。此外,您已经不知道您是否使用了可能的最小值。使用定义的常量,您可以保证使用尽可能小的值,并且您的代码将在操作系统更改后继续存在。
  • @Chris:恐怕你不明白。我不返回一个非常小的值,而是一个像素大小的倍数,以便绘图保持像素对齐(以获得良好的性能和清晰度)。然后我使用内容插图来抵消它。这在未来不太可能改变,因为它是一个相当大的可见距离,操作系统不能忽略。
  • +1 不使用小数像素值作为 UI 偏移量。
【解决方案2】:

这是如何在 UITableView 中隐藏第一节标题(分组样式)。

Swift 3.0 & Xcode 8.0 解决方案

  1. TableView 的委托应该实现 heightForHeaderInSection 方法

  2. 在 heightForHeaderInSection 方法中,返回最小的正数。 (不是零!)

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    
        let headerHeight: CGFloat
    
        switch section {
        case 0:
            // hide the header
            headerHeight = CGFloat.leastNonzeroMagnitude
        default:
            headerHeight = 21
        }
    
        return headerHeight
    }
    

【讨论】:

  • 返回 CGFloat.leastNonzeroMagnitude 而不是 0 对我有帮助。谢谢!
  • 完美答案,谢谢
  • 顺便说一下,objcCGFLOAT_MINSwift中的CGFloat.leastNonzeroMagnitude 相同
  • 如果我希望其他标头的内容来定义标头大小而不是静态/硬编码的 21,该怎么办?
【解决方案3】:

这个答案对我和我的团队来说很有趣,而且工作起来就像一个魅力

  • 在 Interface Builder 中,只需将 tableview 移动到另一个视图下 在视图层次结构中。

原因:

我们观察到这种情况仅发生在 View Hierarchy 中的第一个 View,如果第一个 View 是 UITableView。所以,所有其他类似的 UITableViews 都没有这个烦人的部分,除了第一个。我们尝试将 UITableView 移出视图层次结构的首位,一切正常。

【讨论】:

  • 滚动表格视图时导航栏的毛玻璃效果还有吗?
  • 当您相应地设置您的 tableView 时,您将获得这种 blur 效果。您需要将contentInset 设置为例如{0, 64, 0, 0} 以从顶部偏移64px(状态栏加上导航栏)。 tableView 需要附加在屏幕顶部,而不是 topLayoutGuide(让它到达导航栏下方)
  • 如果你不使用 pull 刷新这看起来不错。
  • 哇。这在 iOS 9 中对我有用,让我大吃一惊。
  • 这应该是公认的答案。好奇怪的虫子!
【解决方案4】:

将此技巧用于分组类型 tableView

viewDidLoad 方法中为您的表格视图复制粘贴以下代码:

tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, tableView.bounds.size.width, 0.01f)];

【讨论】:

  • 我没有尝试过,但我怀疑这个解决方案与其他一些建议的解决方案有相同的缺点:绘图不再与像素对齐,导致模糊并降低性能。模拟器可以揭示它:它可以选择突出显示有问题的对齐。但是,如果它确实向下舍入为 0,那么它确实是一个不错的解决方案。
  • 是的,我猜它确实会向下舍入到 0。因为我多次使用它,但在图纸中没有发现任何模糊。
  • TableHeaderView 和 Section Header 视图?有什么区别,
  • 或略短:_tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 1)].
  • @AsifHabib:tableHeaderView 位于所有表格元素的顶部。它是表本身的标题视图。部分标题视图是放置在每个部分上的视图。根据表中指定的节数,可以有许多节标题视图。但是,只有一个表头视图。
【解决方案5】:

这样就可以了。

override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    if section == 0 {
        return CGFloat.min
    }
    return 25
}

override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    if section == 0 {
        return nil
    }else {
        ...
    }
}

【讨论】:

  • 这是我的解决方案的一个很好的变体,除了它使用小数值。这样,文本和图像不再与像素对齐,绘图速度变慢,结果可能变得模糊。模拟器有“颜色未对齐的图像”选项来揭示这个问题。
  • 对于像我这样使用带有 containerView 的静态单元格的人来说效果很好
  • Swift 3 > 'CGFloat.min' 已重命名为 'CGFloat.leastNormalMagnitude'
【解决方案6】:

我刚刚复制了您的代码并尝试了。它运行正常(在模拟器中尝试过)。我附上了结果视图。你想要这样的观点,对吧?还是我误解了你的问题?

【讨论】:

  • 是的,这基本上就是我想要的,除了我的表格视图位于导航控制器中。这会有所作为吗?
  • 我将 tableView 添加到导航控制器,您的情况出现了:) 我认为在 iOS 7 中,默认情况下在分组样式表视图中修复了此标题高度。通过更改 tableView 的框架,可以隐藏第一个标题视图。(如 set x = 0 y = -40)。但是,我知道这个解决方案不是一个好的解决方案。
  • 非常感谢您的工作。所以似乎只有当表格视图使用分组样式并且包含在导航控制器中时才会出现问题。
  • 尝试从 viewcontroller 更改为 tableviewcontroller 我无法解决标题的问题。也许我错过了试图转换它的东西。 (iOS 7.0.3 sim)
  • 这个问题也出现在这个快照中!第 0 个单元格不是从 x:0.0f & y:0.0f 开始的。
【解决方案7】:

Swift3 : heightForHeaderInSection 适用于 0,您只需确保将 header 设置为 clipsToBounds。

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
       return 0
}

如果你不设置 clipsToBounds 隐藏标题将在滚动时可见。

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    guard let header = view as? UITableViewHeaderFooterView else { return }

    header.clipsToBounds = true
}

【讨论】:

  • clipsToBound = true 如果您打算完全隐藏部分标题视图,则非常重要。将其高度设置为 0/CGFLOAT_MIN 是不够的。
【解决方案8】:

更新[9/19/17]:旧答案在 iOS 11 中不再适用于我。感谢 Apple。以下是:

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 20.0f;
self.tableView.contentInset = UIEdgeInsetsMake(-18.0, 0.0f, 0.0f, 0.0);

上一个答案:

Chris Ostomo 在 cmets 中发布的内容对我有用:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return CGFLOAT_MIN; // to get rid of empty section header
}

【讨论】:

  • 我怀疑您的表格视图的内容不再与像素对齐,导致模糊并降低性能。模拟器可以揭示它:它可以选择突出显示有问题的对齐。但是,如果它确实向下舍入为 0,那么它确实是一个不错的解决方案。
  • 不,我没有发现任何内容问题。约束似乎很好。
  • 好!不再适用于 iOS 11!我的修复持续了不到一周.. ?
【解决方案9】:

以下是如何在 Swift 中删除分组 UITableView 中的顶部部分标题:

tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: CGFloat.leastNormalMagnitude))

【讨论】:

    【解决方案10】:

    在 Swift 4.2 和许多早期版本中,您可以将其他标题设置为 nil,而不是像其他答案中那样将第一个标题的高度设置为 0。假设您有两个部分,并且只希望第二个部分(即1)有一个标题。该标题将包含文本 Foobar:

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return section == 1 ? "Foobar" : nil
    }
    

    【讨论】:

      【解决方案11】:

      如果您想完全删除所有部分标题,请尝试此操作

      func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
          return CGFloat.leastNormalMagnitude
      }
      
      func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
          return CGFloat.leastNormalMagnitude
      }
      

      【讨论】:

      • 这正是我所需要的。一个简单易行的解决方案。 1+
      【解决方案12】:

      我还不能发表评论,但我想我会补充一点,如果你的控制器上有一个UISearchControllerUISearchBar 作为你的tableHeaderView,那么在heightForHeaderInSection 中将第一部分的高度设置为 0 即可确实有效。

      我使用self.tableView.contentOffset = CGPointMake(0, self.searchController.searchBar.frame.size.height);,所以搜索栏默认是隐藏的。

      结果是第一部分没有标题,向下滚动会在第一行的正上方显示搜索栏。

      【讨论】:

        【解决方案13】:

        目前最简单的方法是在不希望显示标题的部分返回 nil"" in func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?

        【讨论】:

          【解决方案14】:

          Swift 版本:Swift 5.1
          大多数情况下,您可以像这样在 tableView 委托中设置高度:

          func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
             return UIView(frame: CGRect(x: 0, y: 0, width: view.width, height: CGFloat.leastNormalMagnitude))
          }
          func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
             return CGFloat.leastNormalMagnitude
          }
          

          有时当你用 Xib 或 Storyboard 创建 UITableView 时,up 的答案不起作用。您可以尝试第二种解决方案:

          let headerView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: CGFloat.leastNormalMagnitude))
          self.tableView.tableHeaderView = headerView
          

          希望它对你有用!

          【讨论】:

            【解决方案15】:

            以下内容适用于 iOS 13.6 和 Xcode 11.6,UITableViewController 嵌入在 UINavigationController 中:

            override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
                nil
            }
            
            override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
                .zero
            }
            

            不需要其他诡计。不使用 UITableViewController 时(即刚刚实现 UITableViewDelegate 方法时)不需要 override 关键字。当然,如果目标只是隐藏第一节的标题,那么这个逻辑可以被包装在一个条件中:

            override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
                if section == 0 {
                    return nil
                } else {
                    // Return some other view...
                }
            }
            
            override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
                if section == 0 {
                    return .zero
                } else {
                    // Return some other height...
                }
            }
            

            【讨论】:

              【解决方案16】:

              在 iOS 15 中,此代码删除了不需要的部分标题空间。

               if #available(iOS 15.0, *) {
                tableView.sectionHeaderTopPadding = .leastNormalMagnitude
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2017-04-24
                • 2017-07-16
                • 2012-01-26
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-11-06
                • 2012-04-02
                相关资源
                最近更新 更多