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


108

随着使用分组样式的表格视图的设计在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问题的答案:从空节隐藏标题似乎表明某些人成功隐藏了标题。但这可能适用于普通样式(而不是分组样式)。

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

更新资料

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


我没有得到那部分=> if(section == 0)return view; 返回零;即返回视图时,其第一部分,否则为零?
2013年

这个想法是为第一部分返回一个高度为0的视图,为所有其他部分返回nil,以便表视图为其使用默认的标题视图。该部分很好地工作; 表格视图显示了这些部分的标题。但第0节的部分无关紧要,因为从未使用调用该方法section == 0
2013年

1
这个答案似乎简短而甜美。stackoverflow.com/a/23955420/3965
罗杰斯先生2015年

Answers:


154

我有一个变通办法,对我来说似乎很干净。所以我在回答我自己的问题。

由于第一部分标题的高度为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)
}

6
使用标头高度0.1f更好地隐藏它。
Chuck Krutsinger 2013年

4
我试过使用0.1f。但是结果是图形不再与像素对齐,从而导致模糊并降低性能。只需在模拟器中尝试即可:它提供了一个选项来突出显示有问题的对齐方式。
2013年

31
实际上,最好使用更好的实现方式(将来不太可能中断),CGFLOAT_MIN而不是使用硬编码的值。换句话说,不要return 1.0f0.1f相反,return CGFLOAT_MIN如果Apple曾经更改了最小可接受值,那么如果您对返回值进行了硬编码,则您将拥有要更改的代码。另外,您已经不知道是否使用了最小值。使用定义的常数,可以确保使用最小的值,并且代码可以在操作系统更改后幸免。
克里斯·奥斯特莫

11
@克里斯:恐怕你不知道。我不会返回非常小的值,而是像素大小的倍数,以便绘图保持像素对齐(以获得良好的性能和清晰度)。然后,我使用内容插图来抵消它。将来这种情况不太可能改变,因为这是一个相当大的可见距离,并且不是操作系统可以忽略的距离。
2014年

8
+1用于不使用小数像素值作为UI偏移。
里卡多·桑切斯·塞兹

52

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

6
返回CGFloat.leastNonzeroMagnitude而不是0帮助了我。谢谢!
anoo_radha

完美的答案,谢谢
Pierre

顺便说一句,CGFLOAT_MIN对于objc等同于CGFloat.leastNonzeroMagnitude斯威夫特
DawnSong

36

答案对我和我的团队都很有趣,并且像一个魅力一样起作用

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

原因:

我们观察到,如果此第一个视图是UITableView,则仅对视图层次结构中的第一个视图会发生这种情况。因此,除第一部分外,所有其他类似的UITableViews都没有此烦人的部分。我们尝试将UITableView移出视图层次结构的第一位,并且一切都按预期进行。


1
滚动表格视图时,是否仍然具有导航栏的磨砂玻璃效果?
2013年

相应地设置tableView时,将产生这种模糊效果。contentInset例如{0, 64, 0, 0},您需要将设置为,使其与顶部的偏移量为64px(状态栏和导航栏)。tableView需要附加在屏幕顶部,而不是topLayoutGuide(使其到达导航栏下方)
Julian F. Weinert

如果您不使用拉动刷新,这看起来会很好。
迈克尔

2
哇。这在iOS 9中对我有用,只是让我大吃一惊。
分配

这应该是公认的答案。如此奇怪的错误!
Oded Harth

25

将此技巧用于分组类型tableView

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

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

我没有尝试过,但是我怀疑此解决方案与其他一些建议的解决方案具有相同的缺点:绘图不再与像素对齐,从而导致模糊并降低性能。模拟器可以显示它:它具有突出显示有问题的对齐方式的选项。但是,如果将其舍入为0,则确实是一个不错的解决方案。
2015年

是的,我想它确实舍入为0。因为我使用了很多次,但是在图纸中没有发现任何模糊。
Nitesh Borad

TableHeaderView和Section Header视图?有什么区别,
AsifHabib

或稍短:_tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 1)]
mojuba

@AsifHabib:tableHeaderView位于所有表元素的顶部。它是表本身的标题视图。节标题视图是放置在每个节上的视图。根据表中指定的节数,可以有许多节标题视图。但是,将只有一个表头视图。
Nitesh Borad'2

21

这样就可以了。

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

2
这是我的解决方案的一个不错的变体,除了它使用分数值。这样,文本和图像不再与像素对齐,绘制速度变慢,结果可能变得模糊。模拟器具有选项“颜色未对齐的图像”以显示此问题。
2015年

对于像我这样的人,将静态单元格与containerView配合使用,效果很好
thibaut noah

3
Swift 3>“ CGFloat.min”已重命名为“ CGFloat.leastNormalMagnitude”
rjobidon

6

我只是复制了您的代码并尝试了。它可以正常运行(在模拟器中试用)。我附上了结果视图。您想要这样的看法,对吗?还是我误会了你的问题?

在此处输入图片说明


1
是的,基本上就是我想要的,除了我的表视图在导航控制器中。会有所作为吗?
2013年

2
我将tableView添加到导航控制器,您的情况出现了:)我认为在iOS 7中,此标题高度修复默认在分组样式表视图中。通过更改tableView的框架,可以隐藏第一个标题视图。(如set x = 0 y = -40)。但是,我知道此解决方案不是一个好的解决方案。
caglar

1
非常感谢您的工作。因此,似乎只有在表视图使用分组样式并包含在导航控制器中时,才会出现该问题。
2013年

试图从viewcontroller更改为tableviewcontroller,我无法解决标题的问题。也许我缺少尝试进行转换的内容。(iOS 7.0.3 sim)
Evgeni Petrov 2014年

1
此快照中也会出现此问题!第0个单元格不是从x:0.0f和y:0.0f开始。
Burhanuddin Sunelwala 2014年

6

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
}

1
如果您计划完全隐藏节标题视图,那么clipsToBound = true非常重要。将其高度设置为0 / CGFLOAT_MIN是不够的。
Altimac

5

更新[9/19/17]:在iOS 11中,旧答案不再适合我。感谢苹果。做到了以下几点:

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

上一个答案:

正如克里斯·奥斯托莫Chris Ostomo)的评论中所述,以下内容对我有用

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

我怀疑表格视图的内容不再与像素对齐,从而导致模糊并降低性能。模拟器可以显示它:它具有突出显示有问题的对齐方式的选项。但是,如果将其舍入为0,则确实是一个不错的解决方案。
科多

不,我没有发现任何内容问题。约束似乎很好。
Manindra Moharana

1
哭!不再适用于iOS 11!我的修正持续了不到一个星期..😞
Manindra Moharana

4

在Swift中,如何在已分组的UITableView中摆脱顶部标题:

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

3

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

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

3

如果要完全删除所有节标题,请尝试此操作

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

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

那只是我所需要的。一个简单的解决方案。1+
iGhost

0

我还不能发表评论,但我想补充一下,如果您UISearchController的控制器上有一个UISearchBaras作为您的tableHeaderView,那么将第一部分的高度设置为0 heightForHeaderInSection确实可以。

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

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


0

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


0

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

希望对你有帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.