无法更改 UITableView 中节标题的文本属性

Posted

技术标签:

【中文标题】无法更改 UITableView 中节标题的文本属性【英文标题】:Cannot change text attributes of section header in UITableView 【发布时间】:2016-03-08 22:58:17 【问题描述】:

我很确定我已经尝试覆盖处理 UITableViewHeaderFooterView 的每个函数,以更改 tableView 部分中标题的文本、字体和 textColor。

我尝试使用从另一个答案中找到的代码:

override func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) 
    let header: UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView
    header.contentView.backgroundColor = UIColor(red: 0/255, green: 181/255, blue: 229/255, alpha: 1.0) 
    header.textLabel!.textColor = UIColor.whiteColor()
    header.alpha = 0.5 
    header.textLabel!.text = "foobar"

这成功地改变了 header.contentView 的背景颜色,但是只要我添加代码行来改变 textLabel 的文本,什么都不会显示(包括背景颜色) .

我可以使用 titleForHeaderInSection 更改文本,但 willDisplayHeaderView 中的代码不会影响文本属性。覆盖 viewForHeaderInSection 似乎也无济于事。有人请帮忙!

【问题讨论】:

【参考方案1】:

在尝试在那里设置任何内容之前,请确保您实际查找的属性具有设置器。

问题

您只设置了contentView,因为它可以与tintColor一起设置,但其他属性标有get,因此您可以获取该值但您没有设置权限它。

来自文档

public var tintColor: UIColor!

public var textLabel: UILabel?  get 
public var detailTextLabel: UILabel?  get  // only supported for headers in grouped style

public var contentView: UIView  get 
public var backgroundView: UIView?

public var reuseIdentifier: String?  get 

解决方案

有一个解决方案可以使用UIAppearance Protocol实现

自定义包含类实例的外观 在容器类的实例或层次结构中的实例中, 使用 appearanceWhenContainedIn: 获取外观代理 班级。例如,要修改条形按钮的外观,基于 包含导航栏的对象:

我们的案例

UILabel.appearanceWhenContainedInInstancesOfClasses([UITableViewHeaderFooterView.self]).textColor = UIColor.whiteColor()

More Details

解决方案 2

您也可以创建自己的UIView 子类并将其显示在

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?

这样你就可以修改你想要的任何东西,而不是试图定制一些在定制方面非常有限的东西

【讨论】:

虽然 textLabel 确实是一个 get only 属性,但 textLabel 的 text 属性是 可设置的,这可以通过我更改 willDisplayHeaderView 中的文本的能力来证明 当我覆盖 titleForHeaderInSection 时。另外,我不希望使用 UIAppearance 协议,因为它仅在 Swift 中支持运行 ios 9 及更高版本的设备。但好消息是我发现了为什么覆盖 viewForHeaderInSection 对我不起作用(为了清楚起见,我想我只是把我自己的答案放进去)!【参考方案2】:

这可能是一个重复的问题,但是在阅读了(很多)不同的解决方案之后,在尝试解决这个问题时,似乎没有一个能够阐明一个重要的难题,我认为摆脱一些问题将是建设性的关于这个问题的补充说明。

TL;DR

要么使用 titleForHeaderInSectionviewForHeaderInSection 要么viewForHeaderInSection 中创建并返回 UILabel 并设置高度heightForHeaderInSection 中的标题。

更详尽的解释

问题的根源: 由于willDisplayHeaderView 的使用不当,我无法更改文本属性。这是因为该函数只能在 一个 UIView(或 UIView 的子类)的标头已经在别处实例化之后使用。除非通过 titleForHeaderInSectionviewForHeaderInSection 来创建标题视图。 参考 titleForHeaderInSection 来自文档:

返回值用作节标题标题的字符串。如果您返回 nil ,则该部分将没有标题。

那么,百万美元的问题:为什么我不能更改 viewForHeaderInSectionwillDisplayHeaderView 中的文本,除非我也设置了文本titleForHeaderInSection 中的部分标题?原来这是一个技巧问题!有点。 在使用 viewForHeaderInSection 的情况下,文本实际上正在发生变化——你只是看不到它。当您使用 titleForHeaderInSection 设置节标题的文本时,swift 会自动为该特定节创建一个具有默认高度约束的 UITableViewHeaderFooterView。创建标题视图的另一种选择是在 viewForHeaderInSection 中创建并返回 UIView 类型的类,但是这里需要注意的是,默认高度约束不会被创建,因此你最终会得到一个高度为零的 UIView 容器,并且它不会显示在屏幕上——但这很容易通过覆盖 heightForHeaderInSection 给它一些高度来解决。 在使用 willDisplayHeaderView 的情况下,由于不正确地实现该功能而存在问题。必须通过在 titleForHeaderInSection 中返回非空字符串值或在 viewForHeaderInSection 中在 willDisplayHeaderView 应该被使用。这是因为该函数中名为“view”的参数必须已经存在,您才能更改它的属性。看起来有点像不费吹灰之力。

解决方案 1

只需确保从 titleForHeaderInSection 返回一个非空字符串值;这样做将确保标题视图对象被实例化。使用 viewForHeaderInSection 将标题的属性设置为您喜欢的。

解决方案 2

重写函数 viewForHeaderInSection 并创建一个继承自 UIView 的新对象(也称为 UILabel、UITableViewHeaderFooterView、UIImageView 或任何适合您的东西)。返回该对象,然后(非常重要!)在 heightForHeaderInSection 中设置标题的高度。此方法无需使用 titleForHeaderInSection。 我还想出了其他几种解决方案,但这两个确实是唯一有意义的解决方案。当然,如果您对使用 Apple 的默认方案的部分标题的外观感到满意,请省去所有麻烦并专门使用 titleForHeaderInSection

【讨论】:

【参考方案3】:

我遇到了同样的问题,并尝试了 darksinge 的答案(解决方案 2)。 仍然没有为我工作。

在我的情况下,添加到解决方案2,我还需要在 willDisplayHeaderView 函数中更改 textLabel 颜色(或 textLabel 的一些其他元素)。 似乎 UIlabel 的内部对象在 willDisplayHeaderView 调用之前被覆盖。(假设对象是 UIlabel 的种类,被覆盖) Here's some complimentary explanation.

这是代码(SearchTableSectionHeaderFooterView 是自定义 UITableViewHeaderFooterView 类。)

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
    return tableView.dequeueReusableHeaderFooterView(withIdentifier: SectionHeaderFooterIdentifier) as! SearchTableSectionHeaderFooterView


override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) 
    // header textLabel color should be modified here
    // ref) https://forums.developer.apple.com/thread/60735
    (view as! SearchTableSectionHeaderFooterView).textLabel?.textColor = UIColor.red


override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? 
    return cells[section].title


override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat 
    return 36

【讨论】:

以上是关于无法更改 UITableView 中节标题的文本属性的主要内容,如果未能解决你的问题,请参考以下文章

无法更改 UILabel 的文本

如何更改 UITableView 中文本的位置?

UITableView reloadData 在没有行的情况下无法工作

按文本宽度iOS对UITableView排序

在 UITableView 中单击时更改 UIButton 颜色和文本

如何更改 UITableHeaderView 的背景颜色和文本颜色