ChatGPT解决这个技术问题 Extra ChatGPT

Changing Font Size For UITableView Section Headers

Can someone please instruct me on the easiest way to change the font size for the text in a UITableView section header?

I have the section titles implemented using the following method:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

Then, I understand how to successfully change the section header height using this method:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

I have the UITableView cells populated using this method:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

However, I'm stuck as to how to actually increase the font size - or for that matter the font style - of the section header text?

Can someone please assist? Thanks.

Swift version

H
HotJard

Another way to do this would be to respond to the UITableViewDelegate method willDisplayHeaderView. The passed view is actually an instance of a UITableViewHeaderFooterView.

The example below changes the font, and also centers the title text vertically and horizontally within the cell. Note that you should also respond to heightForHeaderInSection to have any changes to your header's height accounted for in the layout of the table view. (That is, if you decide to change the header height in this willDisplayHeaderView method.)

You could then respond to the titleForHeaderInSection method to reuse this configured header with different section titles.

Objective-C

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
    UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;

    header.textLabel.textColor = [UIColor redColor];
    header.textLabel.font = [UIFont boldSystemFontOfSize:18];
    CGRect headerFrame = header.frame;
    header.textLabel.frame = headerFrame;
    header.textLabel.textAlignment = NSTextAlignmentCenter;
}

Swift 1.2

(Note: if your view controller is a descendant of a UITableViewController, this would need to be declared as override func.)

override func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) 
{
    let header:UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView

    header.textLabel.textColor = UIColor.redColor()
    header.textLabel.font = UIFont.boldSystemFontOfSize(18)
    header.textLabel.frame = header.frame
    header.textLabel.textAlignment = NSTextAlignment.Center
}

Swift 3.0

This code also ensures that the app doesn't crash if your header view is something other than a UITableViewHeaderFooterView:

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    guard let header = view as? UITableViewHeaderFooterView else { return }
    header.textLabel?.textColor = UIColor.red
    header.textLabel?.font = UIFont.boldSystemFont(ofSize: 18)
    header.textLabel?.frame = header.bounds
    header.textLabel?.textAlignment = .center
}

This method worked much better for me than the one above
Best answer I have seen.
This would be the "proper" way to adjust the information, assuming there is no other reason to subclass (such as adding views, for example). Additionally, this method can be used to update the header text for Dynamic Type. Simply use: header.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; and/or header.detailTextLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; along with the other steps needed (see here: captechconsulting.com/blog/john-szumski/…)
This does not resize the header view, so if your font is larger or significantly different, such as Zapfino (don't ask why), it will cut the text out. If you have to calculate the size on your own, it's a mess and you shouldn't do it.
@CocoaPriest Not crashing in my beta version, tho. (GM seed 2)
t
tarleb

Unfortunately, you may have to override this:

In Objective-C:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

In Swift:

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

Try something like this:

In Objective-C:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

    UILabel *myLabel = [[UILabel alloc] init];
    myLabel.frame = CGRectMake(20, 8, 320, 20);
    myLabel.font = [UIFont boldSystemFontOfSize:18];
    myLabel.text = [self tableView:tableView titleForHeaderInSection:section];

    UIView *headerView = [[UIView alloc] init];
    [headerView addSubview:myLabel];

    return headerView;
}

In Swift:

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

    let myLabel = UILabel()
    myLabel.frame = CGRect(x: 20, y: 8, width: 320, height: 20)
    myLabel.font = UIFont.boldSystemFont(ofSize: 18)
    myLabel.text = self.tableView(tableView, titleForHeaderInSection: section)

    let headerView = UIView()
    headerView.addSubview(myLabel)

    return headerView
}

Thank you. This worked perfectly. Much appreciated.
While this is a correct solution, be careful with this method. For a header longer than one line, you will have to perform the calculations of the height of the header in tableView:heightForHeaderInSection: which can be cumbersome.
Tried this and while it works if you scroll the table up, the Header Label stays on the screen and overlays the cells. :(
@trss I think you will find this is not expected behavior. I'm not talking about the header section staying there, only the label, and its super imposed on the cells as they pass under it making it look a real mess. I did find a better way to achieve this and will post it back once I find it again.
@mosca1337 there is no need for creating another view, you can get the actual 'UITableViewHeaderFooterView' being displayed and adjust parameters.
L
Léo Natan

While mosca1337's answer is a correct solution, be careful with that method. For a header with text longer than one line, you will have to perform the calculations of the height of the header in tableView:heightForHeaderInSection: which can be cumbersome.

A much preferred method is to use the appearance API:

[[UILabel appearanceWhenContainedIn:[UITableViewHeaderFooterView class], nil] setFont:[UIFont boldSystemFontOfSize:28]];

This will change the font, while still leaving the table to manage the heights itself.

For optimal results, subclass the table view, and add it to the containment chain (in appearanceWhenContainedIn:) to make sure the font is only changed for the specific table views.


If subclassing then you would anyway be returning a custom view from - tableView:viewForHeaderInSection: right? In which case the font can be set right there. This is what @mosca1337's solution does anyway.
Haha, well I am a woozey after yesterday. Subclass the table view and add it to container list. ;-)
This solution causes many bugs with calculating of real footer/header size. I can show some examples when the titles gets cutted while custom font is set up.
Swift 3: UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = UIFont.boldSystemFont(ofSize: 28)
This doesn't resize the label correctly to fit the font on iOS 11. Also, scrolling up and down after loading the views resets them to the default font.
M
Maria

For iOS 7 I use this,


-(void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;

    header.textLabel.font = [UIFont boldSystemFontOfSize:10.0f];
    header.textLabel.textColor = [UIColor orangeColor];
}

Here is Swift 3.0 version with header resizing

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    if let header = view as? UITableViewHeaderFooterView {
        header.textLabel!.font = UIFont.systemFont(ofSize: 24.0)
        header.textLabel!.textColor = UIColor.orange          
    }
}

This will not size the header view to fit the new font.
@LeoNatan How can we size the header view to fit the new font - can it be done in this method?
I wanted to clarify that I did see your above answer but I only want to change the font to limit the size when a user selected font (accessibility) exceeds a certain size (so, not all of the time). I believe I need to check and possibly change the font in willDisplayHeaderView, so is there a way I could recalc the view height if the font is changed?
z
ziligy

Swift 3:

Simplest way to adjust only size:

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

    let header = view as! UITableViewHeaderFooterView

    if let textlabel = header.textLabel {
        textlabel.font = textlabel.font.withSize(15)
    }
}

That is the easiest way I am looking for.
Works in swift 4! Don’t forget "override func.."
P
Paulo Henrique Nonaka

Swift 2.0:

Replace default section header with fully customisable UILabel.

Implement viewForHeaderInSection, like so:

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

    let sectionTitle: String = self.tableView(tableView, titleForHeaderInSection: section)!
    if sectionTitle == "" {
      return nil
    }

    let title: UILabel = UILabel()

    title.text = sectionTitle
    title.textColor = UIColor(red: 0.0, green: 0.54, blue: 0.0, alpha: 0.8)
    title.backgroundColor = UIColor.clearColor()
    title.font = UIFont.boldSystemFontOfSize(15)

    return title
  }

Alter the default header (retains default).

Implement willDisplayHeaderView, like so:

  override func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

    if let view = view as? UITableViewHeaderFooterView {
      view.backgroundView?.backgroundColor = UIColor.blueColor()
      view.textLabel!.backgroundColor = UIColor.clearColor()
      view.textLabel!.textColor = UIColor.whiteColor()
      view.textLabel!.font = UIFont.boldSystemFontOfSize(15)
    }
  }

Remember: If you're using static cells, the first section header is padded higher than other section headers due to the top of the UITableView; to fix this:

Implement heightForHeaderInSection, like so:

  override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

    return 30.0 // Or whatever height you want!
  }

S
Sreekanth G

Here it is, You have to follow write a few methods here. #Swift 5

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    
    let header = view as? UITableViewHeaderFooterView
    header?.textLabel?.font = UIFont.init(name: "Montserrat-Regular", size: 14)
    header?.textLabel?.textColor = .greyishBrown
}

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

Have a good luck


A
Anup Gupta

With this method you can set font size, font style and Header background also. there are have 2 method for this

First Method

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section{
        UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
        header.backgroundView.backgroundColor = [UIColor darkGrayColor];
        header.textLabel.font=[UIFont fontWithName:@"Open Sans-Regular" size:12];
        [header.textLabel setTextColor:[UIColor whiteColor]];
    }

Second Method

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 30)];
//    myLabel.frame = CGRectMake(20, 8, 320, 20);
    myLabel.font = [UIFont fontWithName:@"Open Sans-Regular" size:12];
    myLabel.text = [NSString stringWithFormat:@"   %@",[self tableView:FilterSearchTable titleForHeaderInSection:section]];

    myLabel.backgroundColor=[UIColor blueColor];
    myLabel.textColor=[UIColor whiteColor];
    UIView *headerView = [[UIView alloc] init];
    [headerView addSubview:myLabel];
    return headerView;
}

G
Giorgio

Swift 4 version of Leo Natan answer is

UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = UIFont.boldSystemFont(ofSize: 28)

If you wanted to set a custom font you could use

if let font = UIFont(name: "font-name", size: 12) {
    UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = font
}

This doesn't resize the frame, unfortunately.
J
Juan Boero

Swift 2:

As OP asked, only adjust the size, not setting it as a system bold font or whatever:

func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        if let headerView = view as? UITableViewHeaderFooterView, textLabel = headerView.textLabel {

            let newSize = CGFloat(16)
            let fontName = textLabel.font.fontName
            textLabel.font = UIFont(name: fontName, size: newSize)
        }
    }

J
JerryH

This is my solution with swift 5.

To fully control the header section view, you need to use the tableView(:viewForHeaderInsection::) method in your controller, as the previous post showed. However, there is a further step: to improve performance, apple recommend not generate a new view every time but to re-use the header view, just like reuse table cell. This is by method tableView.dequeueReusableHeaderFooterView(withIdentifier: ). But the problem I had is once you start to use this re-use function, the font won't function as expected. Other things like color, alignment all fine but just font. There are some discussions but I made it work like the following.

The problem is tableView.dequeueReusableHeaderFooterView(withIdentifier:) is not like tableView.dequeneReuseCell(:) which always returns a cell. The former will return a nil if no one available. Even if it returns a reuse header view, it is not your original class type, but a UITableHeaderFooterView. So you need to do the judgement and act according in your own code. Basically, if it is nil, get a brand new header view. If not nil, force to cast so you can control.

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let reuse_header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "yourHeaderID")
        if (reuse_header == nil) {
            let new_sec_header = YourTableHeaderViewClass(reuseIdentifier:"yourHeaderID")
            new_section_header.label.text="yourHeaderString"
            //do whatever to set color. alignment, etc to the label view property
            //note: the label property here should be your custom label view. Not the build-in labelView. This way you have total control.
            return new_section_header
        }
        else {
            let new_section_header = reuse_section_header as! yourTableHeaderViewClass
            new_sec_header.label.text="yourHeaderString"
            //do whatever color, alignment, etc to the label property
            return new_sec_header}

    }

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

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now