无法更改 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
要么使用 titleForHeaderInSection 和 viewForHeaderInSection 要么 在 viewForHeaderInSection 中创建并返回 UILabel 并设置高度heightForHeaderInSection 中的标题。
更详尽的解释
问题的根源: 由于willDisplayHeaderView 的使用不当,我无法更改文本属性。这是因为该函数只能在 一个 UIView(或 UIView 的子类)的标头已经在别处实例化之后使用。除非通过 titleForHeaderInSection 或 viewForHeaderInSection 来创建标题视图。 参考 titleForHeaderInSection 来自文档:
返回值用作节标题标题的字符串。如果您返回 nil ,则该部分将没有标题。
那么,百万美元的问题:为什么我不能更改 viewForHeaderInSection 或 willDisplayHeaderView 中的文本,除非我也设置了文本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 中节标题的文本属性的主要内容,如果未能解决你的问题,请参考以下文章
UITableView reloadData 在没有行的情况下无法工作