简体   繁体   English

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

[英]Cannot change text attributes of section header in UITableView

I'm pretty sure I've tried overriding every function that deals with a UITableViewHeaderFooterView to change the text, font, and textColor for the header in a tableView section. 我敢肯定,我已经尝试过覆盖处理UITableViewHeaderFooterView的每个函数,以更改tableView部分中标头的文本,字体和textColor。

I tried using this code found from another answer: 我尝试使用从另一个答案中找到的这段代码:

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"
}

This successfully changed the background color of the header.contentView , however as soon as I add the line of code to change the text of the textLabel, nothing (including the background color) displays at all. 这成功地改变了header.contentView的背景颜色,但只要我添加的代码行更改为textLabel的文字,没有什么(包括背景色)显示在所有。

I am able to change the text with titleForHeaderInSection but the code in willDisplayHeaderView does nothing to effect the text attributes. 我可以使用titleForHeaderInSection更改文本,但是willDisplayHeaderView中的代码不会影响文本属性。 Overriding viewForHeaderInSection also seems to do nothing. 覆盖viewForHeaderInSection似乎也无济于事。 Someone please help! 有人请帮忙!

Before trying to set anything there, make sure that the properties you are actually looking for have setters. 尝试在此处设置任何内容之前,请确保您实际要查找的属性具有设置器。

Issue 问题

You are setting only the contentView because it can be set alongside with the tintColor , but the other properties are marked with get , so you can get the value but you don't have the permission to set it. 您仅设置contentView因为它可以与tintColor一起设置,但是其他属性都标有get ,因此您可以获取该值,但无权对其进行设置。

From Docs 从文档

 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 } 

Solution

There is a solution which can be achieved using UIAppearance Protocol 有一个可以使用UIAppearance协议实现的解决方案

To customize the appearances for instances of a class when contained within an instance of a container class, or instances in a hierarchy, use appearanceWhenContainedIn: to get the appearance proxy for the class. 若要自定义包含在容器类的实例或层次结构中的实例时的类实例的外观,请使用appearanceWhenContainedIn:获取该类的外观代理。 For example, to modify the appearance of bar buttons, based on the object that contains the navigation bar: 例如,根据包含导航栏的对象来修改栏按钮的外观:

Our case 我们的情况

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

More Details 更多细节

Solution 2 解决方案2

You can also create your own subclass of UIView and showing it under 您还可以创建自己的UIView子类并将其显示在

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

This way you can modify whatever you want, rather than trying to customize something that is very limited at customization 这样,您可以修改所需的任何内容,而不必尝试自定义非常有限的内容

This could possibly be a duplicate question, but after reading (a lot) of different solutions, none of them seemed to clarify an important piece of the puzzle when trying to resolve this issue and I think it will be constructive to shed some additional light on this problem. 这可能是一个重复的问题,但是在阅读(了大量)不同的解决方案之后,它们似乎都没有阐明尝试解决此问题时的一个重要难题,我认为进一步阐明这一点将具有建设性。这个问题。

TL;DR TL; DR

Either use titleForHeaderInSection in conjunction with viewForHeaderInSection or create and return a UILabel in viewForHeaderInSection and set the height of the header in heightForHeaderInSection . 无论是在结合使用titleForHeaderInSectionviewForHeaderInSection 创建并返回在viewForHeaderInSection一个UILabel并设置在heightForHeaderInSection头的高度。

More thorough explanation 更详尽的解释

The Root of the Problem: 问题的根源:
I was unable to change the text attributes because of an inappropriate use of willDisplayHeaderView . 由于willDisplayHeaderView的使用不当,我无法更改文本属性。 This is because this function should only be used after a UIView (or subclass of UIView) for the header has already been instantiated elsewhere. 这是因为仅应其他地方实例化标题的UIView(或UIView的子类) 之后才能使用此函数。 The header view does not get created unless done so through titleForHeaderInSection or viewForHeaderInSection . 除非通过titleForHeaderInSectionviewForHeaderInSection进行创建,否则不会创建标题视图。

Referring to titleForHeaderInSection From the docs: 从文档中引用titleForHeaderInSection

Return Value 返回值
A string to use as the title of the section header. 一个字符串,用作节标题的标题。 If you return nil , the section will have no title. 如果返回nil,则该部分将没有标题。

So, the million dollar question: Why couldn't I change the text in viewForHeaderInSection or willDisplayHeaderView unless I also set the text for a section header in titleForHeaderInSection ? 那么,百万美元的问题:为什么我不能更改viewForHeaderInSectionwillDisplayHeaderView中的文本,除非我也为titleForHeaderInSection中的节标题设置了文本?
Turns out this is a trick question! 原来这是一个技巧问题! Sort of. 有点。

In the case of using viewForHeaderInSection , the text actually is getting changed - you just can't see it. 在使用viewForHeaderInSection的情况下,文本实际上正在更改-您只是看不到它。 When you set the text of a section title with titleForHeaderInSection , swift automatically creates a UITableViewHeaderFooterView with a default height constraint for that particular section. 当您使用titleForHeaderInSection设置节标题的文本时,swift会自动为该节创建一个具有默认高度限制的UITableViewHeaderFooterView。 Another option for creating a header view is to create and return a class of type UIView in viewForHeaderInSection , however the caveat here is that a default height constraint does not get created , thus you end up with a UIView container with a height of zero and it will not display onscreen - but this is easily remedied by giving it some height by overriding heightForHeaderInSection . 创建标题视图的另一种方法是在viewForHeaderInSection中创建并返回UIView类型的类,但是要注意的是, 没有创建默认的高度约束 ,因此最终得到高度为零的UIView容器,并且它不会在屏幕上显示-但这可以通过重写heightForHeaderInSection来给它一些高度来解决。

In the case of using willDisplayHeaderView , the problem existed as a result of incorrectly implementing that function. 在使用willDisplayHeaderView的情况下,由于不正确地实现该功能而导致存在该问题。 A header of class type UIView must be created either through returning a non-empty string value in titleForHeaderInSection or returning an object of class type UIView in viewForHeaderInSection before willDisplayHeaderView should be used. 类类型的UIView的报头必须被创建或者通过返回在titleForHeaderInSection一个非空字符串值或返回willDisplayHeaderView之前在viewForHeaderInSection类类型的UIView的目的应该被使用。 This is because the parameter named "view" in that function must already exist before you can change it's properties. 这是因为该函数中名为“ view”的参数必须已经存在 ,才能更改其属性。 Seems kind of like a no-brainer. 似乎有点不费吹灰之力。

Solution 1 解决方案1

Simply make sure you return a non-empty string value from titleForHeaderInSection ; 只需确保您从titleForHeaderInSection返回一个非空字符串值即可 doing so will ensure that a header view object is instantiated. 这样做将确保实例化标题视图对象。 Use viewForHeaderInSection to set the properties of the header to your liking. 使用viewForHeaderInSection可以根据自己的喜好设置标题的属性。

Solution 2 解决方案2

Override the function viewForHeaderInSection and create a new object that inherits from UIView (aka, UILabel, UITableViewHeaderFooterView, UIImageView, or whatever fits your fancy). 覆盖函数viewForHeaderInSection并创建一个继承自UIView的新对象(aka,UILabel,UITableViewHeaderFooterView,UIImageView或任何您喜欢的对象)。 Return that object, and then (very important!) set the height of the header in heightForHeaderInSection . 返回该对象,然后(非常重要!)在heightForHeaderInSection中设置标题的高度。 There is no need to use titleForHeaderInSection with this approach. 无需通过这种方法使用titleForHeaderInSection

There are several other solutions I was able to come up with, but these two are really the only ones that make any sense. 我还可以提出其他几种解决方案,但实际上这两种是唯一有意义的解决方案。 And of course, if you are happy with the way your section headers look using Apple's default scheme, save yourself all the trouble and use titleForHeaderInSection exclusively. 当然,如果您对使用Apple的默认方案的标题标题感到满意,请省去所有麻烦,并单独使用titleForHeaderInSection

I had the same issue and tried the answer by darksinge (solution 2). 我遇到了同样的问题,并尝试了Darksinge的答案(解决方案2)。 Still didn't work for me. 仍然没有为我工作。

In my case, adding to solution2, I also need to change textLabel color(or some other elements of textLabel) at willDisplayHeaderView function. 就我而言,添加到solution2时,我还需要在willDisplayHeaderView函数中更改textLabel颜色(或textLabel的其他元素)。 Seems internally object of UIlabel is overwritten before willDisplayHeaderView called.(assume if the object isKind of UIlabel, overwritten) Here's some complimentary explanation. 似乎内部的UIlabel对象在调用willDisplayHeaderView之前被覆盖。(假设对象是UIlabel的实物,则被覆盖) 这是一些补充说明。

here's the code (SearchTableSectionHeaderFooterView is custom UITableViewHeaderFooterView class.) 这是代码(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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM