将UITableView节标题返回CGFloat.leastNormalMagnitude会导致崩溃。

10
我制作了一个iOS 8应用程序,其中一个页面使用了分组的UITableView。它有多个部分,其中使用CGFloat.leastNormalMagnitude(或Swift 2及以下版本中的CGFloat.min)来移除节标题和页脚高度的“默认”间距。一切顺利,直到在iOS 9和10上运行应用时出现崩溃并显示以下错误:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'section header height must not be negative - provided height for section 0 is -0.00000'

不知何故,任何小于1的值(除了四舍五入的0)都被视为负数-将1作为返回值将使标题/页脚空间再次出现。
有没有解决这个问题的方法?
提前致谢。

CGFloat.leastNormalMagnitude被视为负数,还是任何小于1.0的值都被视为负数? - user3581248
是的,我不知道为什么 :| - edopelawi
你尝试过返回0吗?这对我有效。 - redent84
返回0将使页眉/页脚上的空间... - edopelawi
5个回答

24

我尝试了几个值作为 tableView(_:heightForHeaderInSection:),并发现:

  • leastNormalMagnitudeleastNonzeroMagnitude 将被视为负数(因此导致崩溃)。
  • 零将使 TableView 返回默认的头/脚高度。
  • 介于零和一之间的任何值都将被视为负数。
  • 一个将使 TableView 返回默认高度。
  • 大于一的任何值(例如1.1)都将设置头/脚的实际高度。

我最终使用 1.1 解决了我的问题。

希望这能帮助到某个人!


我不明白你是如何通过设置1.1来解决问题的。 如果你将高度设置为1.1,你仍然会得到非零空间作为你的部分标题,对吧? - Salah
@Salah 是的,我最终使用了一个视图来填充1.1的区域,该视图使用与表格视图相同的背景颜色。 - edopelawi
5
这只是悲哀的行为。 - Jakub Truhlář
@JakubTruhlář,而且还没有记录,但是没关系,生活还要继续 :) - edopelawi

4

我们在使用 Swift 5 和 Xcode 10.2 运行 iOS 9 时遇到了同样的问题。事实证明,如果在 estimatedHeightForHeaderInSection / estimatedHeightForFooterInSection 中返回 CGFloat.leastNormalMagnitude 或 CGFloat.leastNonzeroMagnitude,则会在 iOS 9 设备上崩溃。

您仍然可以在 heightForHeaderInSection / heightForFooterInSection 中返回 leastNormalMagnitude 或 leastNonzeroMagnitude。

正如 edopelawi 在上面指出的那样,任何小于1的值都将被视为负数,而1将被视为默认的分组部分头部或尾部高度。如果设备运行的是 iOS 10 或更低版本,则最终高度我们选择返回 1.000001:


func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
    if #available(iOS 11.0, *) {
        return self.tableView(tableView, heightForHeaderInSection: section)
    } else {
        return max(1.000001, self.tableView(tableView, heightForHeaderInSection: section))
    }
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    if section == 0 {
        return 10
    }
    return CGFloat.leastNonzeroMagnitude
}

1

如果我使用以下代码设置节标题的高度,会遇到相同的问题:

tableView.sectionHeaderHeight = UITableViewAutomaticDimension
tableView.estimatedSectionHeaderHeight = CGFloat.leastNormalMagnitude

但是,如果我将我的控制器设置为表格视图的代理(UITableViewDelegate),并实现:

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

然后它就有效了


谢谢您的回复,但我的问题出现在未手动设置tableView的sectionHeaderHeightestimatedSectionHeaderHeight时,UITableviewDelegate被设置了。 :( - edopelawi

0
也许你需要的是 CGFloat.leastNonzeroMagnitude

谢谢您的回答,但是它仍然在那个值处崩溃了 :( - edopelawi

0
如果您实现了viewForHeader和viewForFooter,就不必作弊。
例如,当我想隐藏标题和/或页脚时,我个人会返回0.1f。此示例将完全隐藏标题和页脚,并且没有填充空间,从而可以添加自定义逻辑。
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 0.1f;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return 0.1f;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
     return nil;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    return nil;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接