351

How can I change color of a section header in UITableView?

EDIT: The answer provided by DJ-S should be considered for iOS 6 and above. The accepted answer is out of date.

Community
  • 1
  • 1
Ilya Suzdalnitski
  • 52,598
  • 51
  • 134
  • 168

34 Answers34

776

This is an old question, but I think the answer needs to be updated.

This method does not involve defining and creating your own custom view. In iOS 6 and up, you can easily change the background color and the text color by defining the

-(void)tableView:(UITableView *)tableView 
    willDisplayHeaderView:(UIView *)view 
    forSection:(NSInteger)section

section delegate method

For example:

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    // Background color
    view.tintColor = [UIColor blackColor];

    // Text Color
    UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
    [header.textLabel setTextColor:[UIColor whiteColor]];

    // Another way to set the background color
    // Note: does not preserve gradient effect of original header
    // header.contentView.backgroundColor = [UIColor blackColor];
}

Taken from my post here: https://happyteamlabs.com/blog/ios-how-to-customize-table-view-header-and-footer-colors/

Swift 3 / 4

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int){
    view.tintColor = UIColor.red
    let header = view as! UITableViewHeaderFooterView
    header.textLabel?.textColor = UIColor.white
}
Peter Kreinz
  • 7,979
  • 1
  • 64
  • 49
Dj S
  • 10,232
  • 1
  • 21
  • 24
  • 4
    I had no idea this had even been added to the SDK. Brilliant! Absolutely the correct answer. – Jarrod Robins Jan 07 '14 at 23:49
  • 1
    OP - Please update the accepted answer to this one. Much cleaner than the old approaches. – Kyle Clegg Jan 27 '14 at 22:17
  • 10
    This doesn't seem to be working for me. The text color works but not the tint for the header background. I am on iOS 7.0.4 – zeeple Feb 07 '14 at 16:30
  • The delegate willDisplayHeaderView is not called sometimes, does anyone have similar issue? – thanhbinh84 Apr 04 '14 at 04:38
  • 11
    user1639164 ,you can use header.backgroundView.backgroundColor=[UIColor blackColor]; to set the tint for the header background. – 慭慭流觞 May 08 '14 at 02:29
  • 1
    Is there any way to make the header opaque? Using this answer it's translucent in iOS 7. – Kent May 09 '14 at 22:43
  • 1
    For iOS8 this is still the right answer. You have to implement -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section and then this method. Then you can change the header's properties. – Tim Daubenschütz Sep 30 '14 at 16:16
  • For anyone wanting a solution using Swift 1.2 with iOS 8+ I have added a solution :) – Max Jun 20 '15 at 07:59
  • 2
    @Kent it's been a while obviously, but for future people the `header.contentView.backgroundColor = [UIColor blackColor];` option will give you an opaque header – SparkyRobinson Oct 10 '17 at 23:10
399

Hopefully this method from the UITableViewDelegate protocol will get you started:

Objective-C:

- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
{
  UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 30)] autorelease];
  if (section == integerRepresentingYourSectionOfInterest)
     [headerView setBackgroundColor:[UIColor redColor]];
  else 
     [headerView setBackgroundColor:[UIColor clearColor]];
  return headerView;
}

Swift:

func tableView(_ tableView: UITableView!, viewForHeaderInSection section: Int) -> UIView!
{
  let headerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: 30))
  if (section == integerRepresentingYourSectionOfInterest) {
    headerView.backgroundColor = UIColor.redColor()
  } else {
    headerView.backgroundColor = UIColor.clearColor()
  }
  return headerView
}

Updated 2017:

Swift 3:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
    {
        let headerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: 30))
        if (section == integerRepresentingYourSectionOfInterest) {
            headerView.backgroundColor = UIColor.red
        } else {
            headerView.backgroundColor = UIColor.clear
        }
        return headerView
    }

Replace [UIColor redColor] with whichever UIColor you would like. You may also wish to adjust the dimensions of headerView.

FluffyKitten
  • 13,824
  • 10
  • 39
  • 52
Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345
  • 17
    It can also help to adjust the section header size using self.tableView.sectionHeaderHeight. Otherwise, you may have trouble seeing the text you display for the section title. – Tony Lenzi Jan 23 '10 at 20:56
  • Works fine with `[UIColor xxxColor]` however when I try a custom colour like ones I can get from photoshop (so using the `UIColor red:green:blue:alpha:`, it is just white. Am I doing something wrong? – Matej Apr 09 '13 at 01:16
  • Post a separate question and we'll try to help. Include source code. – Alex Reynolds Apr 09 '13 at 07:29
  • 12
    Note that this answer (while correct) will simply return a UIView with no content. – Greg M. Krsak Oct 14 '13 at 19:06
  • Unless the person asking the question defines explicitly what kind of view they are trying to create, then any answer can, at best, only demonstrate the general idea of what can be done. Hope this is helpful for you, Greg. – Alex Reynolds Dec 22 '13 at 18:27
  • i can even set the size of 0 and it will still work: CGRectMake(0, 0, 0, 0) – catamphetamine Jan 11 '14 at 17:06
  • You can anonymously downvote this, whoever you are, but I still answered the question correctly. Cheers! – Alex Reynolds Jul 22 '14 at 22:41
  • 7
    This is pretty outdated information and simply creating another view isn't the best answer. The idea is to get the proper view and change the color or tint on it. The answer below using willDisplayHeaderView is a much better approach. – Alex Zavatone Nov 04 '15 at 13:52
  • The @DjS answer below is a better solution, for sure, but to make this answer work with text in the header, simply create and return a `UILabel` (filled in appropriately) rather than a blank `UIView`. – Grimxn Sep 08 '17 at 08:57
  • How to set the frame of the header view to respect the safe area margins? – Jahir Fiquitiva Jul 29 '18 at 01:16
99

Here's how to change the text color.

UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(10, 3, tableView.bounds.size.width - 10, 18)] autorelease];
label.text = @"Section Header Text Here";
label.textColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.75];
label.backgroundColor = [UIColor clearColor];
[headerView addSubview:label];
pkamb
  • 33,281
  • 23
  • 160
  • 191
DoctorG
  • 1,168
  • 7
  • 11
  • 18
    Thanks DoctorG - This was useful. BTW - to keep the existing label provided by the dataSource, I modified the 2nd line like so: label.text = [tableView.dataSource tableView:tableView titleForHeaderInSection:section]; Might be bad form, but it worked for me. Maybe this can help someone else. – JJ Rohrer Mar 16 '11 at 16:25
  • 1
    @JJ That form is actually fine, since you're calling the same method you'd initially use to define the table's section header. – Tim Jun 11 '11 at 18:44
  • 3
    I removed the autorelease and changed it to an explicit release. UITableView formatting methods are called many, many times. Avoid using autorelease when possible. – memmons Jun 30 '11 at 22:54
  • @Harkonian, rather than change the submitted answer, please recommend the change in a comment to the answer. It's considered bad form to change other people's code with an edit. Spelling errors, and bad formatting and grammar are fair game. – the Tin Man Jun 30 '11 at 23:50
  • 1
    Instead of addSubview:UILabel, you should just be returning UILabel in viewForHeaderInSection. UILable is-a UIView already :) – Nas Banov Oct 20 '11 at 08:35
  • You'll want to add the UILabel as a subview if you want the label placed relative to the header view he's creating. For example, if you want to shift the label 20 pixels to the right to match placement of the default label. – tyler Mar 22 '12 at 00:31
  • Keep in-mind that a UILabel's default text style may be different than a UITableView section's default text style. You may need to adjust your label to match the appropriate style. – Greg M. Krsak Oct 14 '13 at 19:14
58

You can do this if you want header with custom color. This solution works great since iOS 6.0.

Objective C:

[[UITableViewHeaderFooterView appearance] setTintColor:[UIColor redColor]];

Swift:

UITableViewHeaderFooterView.appearance().tintColor = .white
Denis Kutlubaev
  • 15,320
  • 6
  • 84
  • 70
Leszek Zarna
  • 3,253
  • 26
  • 26
34

The following solution works for Swift 1.2 with iOS 8+

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

    // This changes the header background
    view.tintColor = UIColor.blueColor()

    // Gets the header view as a UITableViewHeaderFooterView and changes the text colour
    var headerView: UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView
    headerView.textLabel.textColor = UIColor.redColor()

}
Max
  • 1,974
  • 2
  • 16
  • 24
25

Setting the background color on UITableViewHeaderFooterView has been deprecated. Please use contentView.backgroundColor instead.

Alex
  • 1,233
  • 2
  • 17
  • 27
22

You can do it on main.storyboard in about 2 seconds.

  1. Select Table View
  2. Go to Attributes Inspector
  3. List item
  4. Scroll down to View subheading
  5. Change "background"

Have a look here

Steve
  • 4,372
  • 26
  • 37
20

Don't forget to add this piece of code from the delegate or your view will be cut off or appear behind the table in some cases, relative to the height of your view/label.

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 30;
}
whyoz
  • 5,168
  • 47
  • 53
18

If you don't want to create a custom view, you can also change the color like this (requires iOS 6):

-(void) tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
    if ([view isKindOfClass: [UITableViewHeaderFooterView class]]) {
        UITableViewHeaderFooterView* castView = (UITableViewHeaderFooterView*) view;
        UIView* content = castView.contentView;
        UIColor* color = [UIColor colorWithWhite:0.85 alpha:1.]; // substitute your color here
        content.backgroundColor = color;
    }
}
William Jockusch
  • 26,513
  • 49
  • 182
  • 323
14

For swift 5 +

In willDisplayHeaderView Method

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

     //For Header Background Color
     view.tintColor = .black

    // For Header Text Color
    let header = view as! UITableViewHeaderFooterView
    header.textLabel?.textColor = .white
}

I hope this helps you :]

theNoobDev10
  • 409
  • 5
  • 6
13

Set the background and text color of section area: (Thanks to William Jockusch and Dj S)

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    if ([view isKindOfClass: [UITableViewHeaderFooterView class]]) {
        UITableViewHeaderFooterView* castView = (UITableViewHeaderFooterView*) view;
        castView.contentView.backgroundColor = [UIColor grayColor];
        [castView.textLabel setTextColor:[UIColor grayColor]];
    }
}
Roozbeh Zabihollahi
  • 7,207
  • 45
  • 39
13

Swift 4

To change the background color, text label color and font for the Header View of a UITableView Section, simply override willDisplayHeaderView for your table view like so:

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        let header = view as! UITableViewHeaderFooterView
        header.backgroundView?.backgroundColor = .white
        header.textLabel?.textColor = .black
        header.textLabel?.font = UIFont(name: "Helvetica-Bold", size: 14)
} 

This worked perfectly for me; hope it does help you too!

Nii Mantse
  • 2,554
  • 2
  • 13
  • 10
  • Setting the background color on UITableViewHeaderFooterView has been deprecated. You must set a custom UIView with your desired background color to the backgroundView property instead. – mojtaba al moussawi Jan 01 '19 at 13:40
10

Here's how to add an image in header view:

- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
{
    UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 30)] autorelease];
    UIImageView *headerImage = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"top-gery-bar.png"]] autorelease];

    headerImage.frame = CGRectMake(0, 0, tableView.bounds.size.width, 30);

    [headerView addSubview:headerImage];

    return headerView;
}
animuson
  • 53,861
  • 28
  • 137
  • 147
Maulik
  • 19,348
  • 14
  • 82
  • 137
9

For iOS8 (Beta) and Swift choose the RGB Color you want and try this:

override func tableView(tableView: UITableView!, viewForHeaderInSection section: Int) -> UIView! {
    var header :UITableViewHeaderFooterView = UITableViewHeaderFooterView()

    header.contentView.backgroundColor = UIColor(red: 254.0/255.0, green: 190.0/255.0, blue: 127.0/255.0, alpha: 1)
    return header

}

(The "override" is there since i´m using the UITableViewController instead of a normal UIViewController in my project, but it´s not mandatory for changing the section header color)

The text of your header will still be seen. Note that you will need to adjust the section header height.

Good Luck.

Corona
  • 685
  • 1
  • 10
  • 15
6

SWIFT 2

I was able to successfully change the section background color with an added blur effect (which is really cool). To change the background color of section easily:

  1. First go to Storyboard and select the Table View
  2. Go to Attributes Inspector
  3. List item
  4. Scroll down to View
  5. Change "Background"

Then for blur effect, add to code:

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

    // This is the blur effect

    let blurEffect = UIBlurEffect(style: .Light)
    let blurEffectView = UIVisualEffectView(effect: blurEffect)

    // Gets the header view as a UITableViewHeaderFooterView and changes the text colour and adds above blur effect
    let headerView: UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView
    headerView.textLabel!.textColor = UIColor.darkGrayColor()
    headerView.textLabel!.font = UIFont(name: "HelveticaNeue-Light", size: 13)
    headerView.tintColor = .groupTableViewBackgroundColor()
    headerView.backgroundView = blurEffectView

}
A.J. Hernandez
  • 969
  • 11
  • 13
6

Swift 4 makes it very easy. Simply add this to your class and set the color as needed.

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        view.backgroundColor = UIColor(red: 0.094, green: 0.239, blue: 0.424, alpha: 1.0)
    }

or if a simple color

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        view.backgroundColor = UIColor.white
    }

Updated for Swift 5

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        view.tintColor = UIColor(red: 0.094, green: 0.239, blue: 0.424, alpha: 1.0)
    }

or if a simple color

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        view.tintColor = UIColor.white
    }
David Sanford
  • 735
  • 12
  • 26
6

For me none of above works after wasting 2 hours what this is the solution. In my case it was custom view but I cannot able to change it from storyboard and view's awakeFromNib for some reason.

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        let header = view as! UITableViewHeaderFooterView
        header.contentView.backgroundColor = .white
    }
SuryaKantSharma
  • 1,113
  • 12
  • 27
5

I know its answered, just in case, In Swift use the following

    override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let tableViewWidth = self.tableView.bounds

        let headerView = UIView(frame: CGRectMake(0, 0, tableViewWidth.size.width, self.tableView.sectionHeaderHeight))
        headerView.backgroundColor = UIColor.greenColor()

        return headerView
    }
arango_86
  • 4,236
  • 4
  • 40
  • 46
4

iOS 8+

func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        tableView.tableHeaderView?.backgroundColor = UIColor.blue()
}
Gent
  • 241
  • 4
  • 7
4

Based on @Dj S answer, using Swift 3. This works great on iOS 10.

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    // Background color
    view.tintColor = UIColor.black

    // Text Color
    let headerView = view as! UITableViewHeaderFooterView
    headerView.textLabel?.textColor = UIColor.white
}
nsinvocation
  • 7,559
  • 3
  • 41
  • 46
3

I have a project using static table view cells, in iOS 7.x. willDisplayHeaderView does not fire. However, this method works ok:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    NSLog(@"%s", __FUNCTION__);
    CGRect headerFrame = CGRectMake(x, y, w, h);    
    UIView *headerView = [[UIView alloc] initWithFrame:headerFrame];  
    headerView.backgroundColor = [UIColor blackColor];
ICL1901
  • 7,632
  • 14
  • 90
  • 138
3
 -(void) tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view
  forSection:(NSInteger)section
  {
        if ([view isKindOfClass: [UITableViewHeaderFooterView class]])
        {
             UITableViewHeaderFooterView *castView = (UITableViewHeaderFooterView *) view;
             UIView *content = castView.contentView;
             UIColor *color = [UIColor whiteColor]; // substitute your color here
             content.backgroundColor = color;
             [castView.textLabel setTextColor:[UIColor blackColor]];
        }
 }
Vinoth
  • 119
  • 1
  • 6
3

I think this code is not so bad.

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerView = tableView.dequeueReusableHeaderFooterViewWithIdentifier(MyHeaderView.reuseIdentifier) as MyHeaderView
    let backgroundView = UIView()
    backgroundView.backgroundColor = UIColor.whiteColor()
    headerView.backgroundView = backgroundView
    headerView.textLabel.text = "hello"
    return headerView
}
mmtootmm
  • 800
  • 6
  • 17
2

In iOS 7.0.4 I created a custom header with it's own XIB. Nothing mentioned here before worked. It had to be the subclass of the UITableViewHeaderFooterView to work with the dequeueReusableHeaderFooterViewWithIdentifier: and it seems that class is very stubborn regarding the background color. So finally I added an UIView (you could do it either with code or IB) with name customBackgroudView, and then set it's backgroundColor property. In layoutSubviews: I set that view's frame to bounds. It work with iOS 7 and gives no glitches.

// in MyTableHeaderView.xib drop an UIView at top of the first child of the owner
// first child becomes contentView

// in MyTableHeaderView.h
@property (nonatomic, weak) IBOutlet UIView * customBackgroundView;

// in MyTableHeaderView.m
-(void)layoutSubviews;
{
    [super layoutSubviews];

    self.customBackgroundView.frame = self.bounds;
}
// if you don't have XIB / use IB, put in the initializer:
-(id)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
    ...
    UIView * customBackgroundView = [[UIView alloc] init];
    [self.contentView addSubview:customBackgroundView];
    _customBackgroundView = customBackgroundView;
    ...
}


// in MyTableViewController.m
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    MyTableHeaderView * header = [self.tableView
                                          dequeueReusableHeaderFooterViewWithIdentifier:@"MyTableHeaderView"];
    header.customBackgroundView.backgroundColor = [UIColor redColor];
    return header;
}
Maksymilian Wojakowski
  • 5,011
  • 3
  • 19
  • 14
2

Just change the color of layer of the header view

- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
{
  UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0,    tableView.bounds.size.width, 30)] autorelease];
 headerView.layer.backgroundColor = [UIColor clearColor].CGColor
}

2

If anyone needs swift, keeps title:

override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let view = UIView(frame: CGRect(x: 0,y: 0,width: self.tableView.frame.width, height: 30))
    view.backgroundColor = UIColor.redColor()
    let label = UILabel(frame: CGRect(x: 15,y: 5,width: 200,height: 25))
    label.text = self.tableView(tableView, titleForHeaderInSection: section)
    view.addSubview(label)
    return view
}
Cmar
  • 141
  • 2
  • 7
2

I got message from Xcode through console log

[TableView] Setting the background color on UITableViewHeaderFooterView has been deprecated. Please set a custom UIView with your desired background color to the backgroundView property instead.

Then I just create a new UIView and lay it as background of HeaderView. Not a good solution but it easy as Xcode said.

Pokotuz
  • 121
  • 1
  • 5
2

In my case, It worked like this:

let headerIdentifier = "HeaderIdentifier"
let header = self.tableView.dequeueReusableHeaderFooterView(withIdentifier: headerIdentifier)
header.contentView.backgroundColor = UIColor.white
Idrees Ashraf
  • 1,363
  • 21
  • 38
2

Just set the background color of the background view:

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int){         
  let tableHeader = view as! UITableViewHeaderFooterView        
  tableHeader.backgroundView?.backgroundColor = UIColor.white     
}
Lukas Mohs
  • 290
  • 3
  • 4
2

If you are using a custom header view:

class YourCustomHeaderFooterView: UITableViewHeaderFooterView { 

override func awakeFromNib() {
    super.awakeFromNib()
    self.contentView.backgroundColor = .white //Or any color you want
}

}

0

With RubyMotion / RedPotion, paste this into your TableScreen:

  def tableView(_, willDisplayHeaderView: view, forSection: section)
    view.textLabel.textColor = rmq.color.your_text_color
    view.contentView.backgroundColor = rmq.color.your_background_color
  end

Works like a charm!

Eli Duke
  • 454
  • 1
  • 3
  • 14
0

Although func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) will work as well, you can acheive this without implementing another delegate method. in you func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? method, you can use view.contentView.backgroundColor = UIColor.white instead of view.backgroundView?.backgroundColor = UIColor.white which is not working. (I know that backgroundView is optional, but even when it is there, this is not woking without implementing willDisplayHeaderView

gutte
  • 1,373
  • 2
  • 19
  • 31
0

Using UIAppearance you can change it for all headers in your application like this:

UITableViewHeaderFooterView.appearance().backgroundColor = theme.subViewBackgroundColor

devjme
  • 684
  • 6
  • 12
0

iOS 13> swift 5

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {view.tintColor = UIColor.red }