ChatGPT解决这个技术问题 Extra ChatGPT

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

由于使用分组样式的表格视图设计在 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

L
Linus Unnebäck

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

由于 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 偏移量。
u
user3378170

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

Swift 3.0 & Xcode 8.0 解决方案

TableView 的委托应该实现 heightForHeaderInSection 方法 在 heightForHeaderInSection 方法中,返回最小的正数。 (不是零!) func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { let headerHeight: CGFloat switch section { case 0: // 隐藏标题 headerHeight = CGFloat.leastNonzeroMagnitude default: headerHeight = 21 } return headerHeight }


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

答案对我和我的团队来说很有趣,而且工作起来很迷人

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

原因:

我们观察到这种情况只发生在 View Hierarchy 中的第一个 View 上,如果第一个 View 是 UITableView。所以,所有其他类似的 UITableView 都没有这个烦人的部分,除了第一个。我们尝试将 UITableView 移出视图层次结构的第一位,并且一切都按预期工作。


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

将此技巧用于分组类型 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 位于所有表格元素的顶部。它是表本身的标题视图。部分标题视图是放置在每个部分上的视图。根据表中指定的节数,可以有许多节标题视图。但是,只有一个表头视图。
T
TonnyTao

这种方式是可以的。

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'
c
caglar

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

https://i.stack.imgur.com/VVrIC.png


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

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 是不够的。
M
Manindra Moharana

更新 [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 在评论中所发布的,以下内容对我有用:

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

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

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

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

A
Avinash

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

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

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

这正是我需要的。一个简单易行的解决方案。 1+
J
JaneGoodall

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

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

R
Rajesh

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

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

R
Raesu

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

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

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


V
Vilém Kurz

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


m
mistdon

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

希望这对你有用!


r
rlziii

以下内容适用于 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...
    }
}

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅