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

由于使用分组样式的表视图的设计在 iOS7中发生了相当大的变化,我想隐藏(或删除)第一部分的标题。到目前为止,我还没有成功。

简单来说,我的代码是这样的:

- (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调用。但仍然使用默认高度绘制空节标题。(在 iOS6中,这两个方法被调用。然而,可见的结果是一样的。)

如果返回不同的值,则部分标题将获得指定的高度。

如果我返回0.01,它几乎是正确的。然而,当我在模拟器中打开“颜色错位图像”时,它会标记所有的表格视图单元格(这似乎是一个蕴涵)。

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

到目前为止,最好的折衷方案是返回高度0.5,导致导航栏下面的线条有点粗。但是,如果有人知道如何完全隐藏第一部分的标题,我将非常感激。

更新

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

123191 次浏览

I just copied your code and tried. It runs normally (tried in simulator). I attached result view. You want such view, right? Or I misunderstood your problem?

enter image description here

我有一个对我来说相当干净的解决办法,所以我要回答我自己的问题。

由于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);
}

Swift:

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

答案对我和我的团队来说非常有趣,而且非常有效

  • 在 Interface Builder 中,只要将桌面视图移到另一个视图下 在视图层次结构中

REASON:

我们观察到 这只发生在视图层次结构中的第一个视图,如果第一个视图是 UITableView。因此,所有其他类似的 UITableView 都没有这个恼人的部分,除了第一个部分。我们尝试将 UITableView 移出视图层次结构中的第一位,一切都按预期运行。

this way is OK.

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 {
...
}
}

对分组类型 tableView 使用此技巧

ViewDidLoad方法为表视图复制下面的代码:

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

我现在还不能评论,但是我想补充一点,如果你的控制器上有一个 UISearchControllerUISearchBar是你的 tableHeaderView,那么在 heightForHeaderInSection中把第一部分的高度设置为0就可以了。

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

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

这是如何在 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
    }
    

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
}

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

更新[9/19/17] : 旧的答案在 iOS11中不再适合我了。感谢苹果。以下是我的回答:

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

上次回答:

正如 克里斯 · 奥斯托莫在评论中指出的那样,以下内容对我很有用:

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

下面是如何去掉分组 UITableView 中的顶部标题,在 Swift 中:

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

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

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

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

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


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

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

希望对你有用!

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

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

在 iOS15中,这段代码删除了不需要的节头空间。

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