UITableViewHeaderFooterView: Unable to change background color

IphoneIosXcodeUitableview

Iphone Problem Overview


I'm trying to change the background color of UITableViewHeaderFooterView. Although the view is appearing, the background color remains the default color. I'm getting a log from xcode saying:

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

However, none of the following options work:

myTableViewHeaderFooterView.contentView.backgroundColor = [UIColor blackColor];
myTableViewHeaderFooterView.backgroundView.backgroundColor = [UIColor blackColor];
myTableViewHeaderFooterView.backgroundColor = [UIColor blackColor];
    

I've also tried changing the background color of the view in the xib file.

Any suggestions? Thanks.

Iphone Solutions


Solution 1 - Iphone

#iOS 8, 9, 10, 11...

The only way to set any color (with any alpha) is to use backgroundView:

Swift

self.backgroundView = UIView(frame: self.bounds)
self.backgroundView.backgroundColor = UIColor(white: 0.5, alpha: 0.5)

Obj-C

self.backgroundView = ({
    UIView * view = [[UIView alloc] initWithFrame:self.bounds];
    view.backgroundColor = [UIColor colorWithWhite: 0.5 alpha:0.5];
    view;
    });

Responses to Comments

  • None of these other options reliably work (despite the comments below)

     // self.contentView.backgroundColor = [UIColor clearColor];
     // self.backgroundColor = [UIColor clearColor];
     // self.tintColor = [UIColor clearColor];
    
  • the backgroundView is resized automatically. (No need to add constraints)

  • Control alpha with UIColor(white: 0.5, alpha: 0.5) or backgroundView.alpha = 0.5.
    (of course, any color will do)

  • When using XIB, make root view a UITableViewHeaderFooterView and associate the backgroundView programmatically:

Register with:

<!-- language: lang-swift -->

    tableView.register(UINib(nibName: "View", bundle: nil),
                       forHeaderFooterViewReuseIdentifier: "header")

Load with:

<!-- language: lang-swift -->

    override func tableView(_ tableView: UITableView,
                            viewForHeaderInSection section: Int) -> UIView? {
        if let header =
            tableView.dequeueReusableHeaderFooterView(withIdentifier: "header") {
            let backgroundView = UIView(frame: header.bounds)
            backgroundView.backgroundColor = UIColor(white: 0.5, alpha: 0.5)
            header.backgroundView = backgroundView
            return header
        }
        return nil
    }

Demo

↻ replay animation

► Find this solution on GitHub and additional details on Swift Recipes.

Solution 2 - Iphone

You should either use myTableViewHeaderFooterView.tintColor, or assign a custom background view to myTableViewHeaderFooterView.backgroundView.

Solution 3 - Iphone

In iOS 7 contentView.backgroundColor worked for me, tintColor did not.

   headerView.contentView.backgroundColor = [UIColor blackColor];

Though clearColor did not work for me, the solution I found is to set backgroundView property to transparent image. Maybe it will help someone:

UIGraphicsBeginImageContextWithOptions(CGSizeMake(1, 1), NO, 0.0);
UIImage *blank = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

headerView.backgroundView = [[UIImageView alloc] initWithImage:blank];

Solution 4 - Iphone

Make sure you set the backgroundColor of the contentView for your UITableViewHeaderFooterView:

self.contentView.backgroundColor = [UIColor whiteColor];

Then it will work.

Solution 5 - Iphone

For me I tried everything stated above but still was getting the warning "Setting the background color on UITableViewHeaderFooterView has been deprecated. Please use contentView.backgroundColor instead." then I tried this: within the xib file the background color for header view was selected to clear color instead of default once I changed it to default the warning went away. was this

Changed to this

Solution 6 - Iphone

For solid background colors, setting the contentView.backgroundColor should be enough:

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    if let headerView = view as? UITableViewHeaderFooterView {
        headerView.contentView.backgroundColor = .red // Works!
    }
}

For colors with transparency, including .clear color, this no longer works:

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    if let headerView = view as? UITableViewHeaderFooterView {
        headerView.contentView.backgroundColor = .clear // Does not work 😞
    }
}

For a full transparent section header, set the backgroundView property to an empty view:

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    if let headerView = view as? UITableViewHeaderFooterView {
        headerView.backgroundView = UIView() // Works!
    }
}

However, beware of possible side effects. Unless the table view is set to "Grouped", section headers will snap at the top when scrolling down. If the section headers are transparent, the cell content will be seen through, which might not look great.

Here, section headers have transparent background:

enter image description here

To prevent this, it is better to set the background of the section header to a solid color (or gradient) matching the background of your table view or view controller.

Here, section headers have a fully opaque gradient background:

enter image description here

Solution 7 - Iphone

For a clear color, I use

self.contentView.backgroundColor = [UIColor clearColor];
self.backgroundView = [UIView new];
self.backgroundView.backgroundColor = [UIColor clearColor];

It seems fine to me.

Solution 8 - Iphone

enter image description hereIn interface builder pull up your .xib, on the top element, in attribute inspector set the background color to default. Then go to the Content View and set the background color there (reference to https://github.com/jiecao-fm/SwiftTheme/issues/24).

Solution 9 - Iphone

On iOS9 headerView.backgroundView.backgroundColor worked for me:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    TableViewHeader *headerView = (TableViewHeader *)[super tableView:tableView viewForHeaderInSection:section];
    headerView.backgroundView.backgroundColor = [UIColor redColor];
}

On iOS8 I was using headerView.contentView.backgroundColor without problems, but now with iOS 9, I was getting a weird issue that made the background color not fill the whole space of the cell. So I tried just headerView.backgroundColor and I got the same error from the OP.

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

So now everything works great and without warnings by using headerView.backgroundView.backgroundColor

Solution 10 - Iphone

If you are customising a section header cell with Storyboard/Nib, then make sure the background color is default for the "Table Section Header" view.

And if you subclass UITableViewHeaderFooterView, and using nib, then what you have to do is to create a IBOutlet for the content view, and name it eg. containerView. This is not to be confused with contentView, which is parent of this container view.

With that setup, you change the background color of containerView instead.

Solution 11 - Iphone

if you created a custom subclass of UITableViewHeaderFooterView with xib file then you should override setBackgroundColor. Keep it empty.

-(void)setBackgroundColor:(UIColor *)backgroundColor {
    
}

And this will solve your problem.

Solution 12 - Iphone

I tried with the appearanceWhenContainedIn chain, and it worked for me.

[[UIView appearanceWhenContainedIn:[UITableViewHeaderFooterView class], [UITableView class], nil] 
         setBackgroundColor: [UIColor.grayColor]];

Solution 13 - Iphone

maybe because the backgroundView doesn't exist

override func draw(_ rect: CGRect){
    // Drawing code
    let view = UIView()
    view.frame = rect
    self.backgroundView = view
    self.backgroundView?.backgroundColor = UIColor.yourColorHere
}

that work for me.

Solution 14 - Iphone

iOS 12, Swift 5. If you are willing (or trying!) to use an appearance proxy, the following solution works:

  1. Subclass UITableViewHeaderFooterView and expose your own appearance proxy setting.
final class MySectionHeaderView: UITableViewHeaderFooterView {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    override init(reuseIdentifier: String?) {
        super.init(reuseIdentifier: reuseIdentifier)
    }
    
    @objc dynamic var forceBackgroundColor: UIColor? {
        get { return self.contentView.backgroundColor }
        set(color) {
            self.contentView.backgroundColor = color
            // if your color is not opaque, adjust backgroundView as well
            self.backgroundView?.backgroundColor = .clear
        }
    }
}
  1. Set the appearance proxy at your desired granularity.
MySectionHeaderView.appearance().forceBackgroundColor = .red

or

MySectionHeaderView.appearance(whenContainedInInstancesOf: [MyOtherClass.self]).forceBackgroundColor = .red

Solution 15 - Iphone

Forget about difficulties.

Add to your project UITableViewHeaderFooterView+BGUpdate.swift with code below:

extension UITableViewHeaderFooterView {
    
    open override var backgroundColor: UIColor? {
        get {
            return self.backgroundColor
        }
        set {
            let bgView = UIView()
            bgView.backgroundColor = newValue
            backgroundView = bgView
        }
    }
}

Usage is simple as you expected before:

headerView.backgroundColor = .red

Usage examples:

  1. In delegate's tableView:viewForHeaderInSection: :
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerView = tv.dequeueReusableHeaderFooterView(withIdentifier: "MyHeaderView")
    headerView.backgroundColor = .red // <- here
    return headerView
}

or

  1. In your custom header view class:
class MyHeaderView: UITableViewHeaderFooterView {

    override func awakeFromNib() {
        super.awakeFromNib()
        backgroundColor = .red // <- here
    }
}

Solution 16 - Iphone

Put this code in initializing of your UITableViewHeaderFooterView subclass:

let bgView = UIView()
bgView.backgroundColor = UIColor.clear
backgroundView = bgView
backgroundColor = UIColor.clear
contentView.backgroundColor = UIColor.clear

Solution 17 - Iphone

Setting the BackgroundView with clear color works fine for visible headers. If the table is scrolled to show headers at bottom ,this solution fails.

P.S.My table consists only of headers without any cells.

Solution 18 - Iphone

Swift:

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView {
	var headerView: TableViewHeader = super.tableView(tableView, viewForHeaderInSection: section) as! TableViewHeader
	headerView.backgroundView.backgroundColor = UIColor.redColor()
}

Solution 19 - Iphone

Create UIView and set background color, then set it to self.backgroundView.

- (void)setupBackgroundColor:(UIColor *) color {
    UIView *bgView = [[UIView alloc] initWithFrame:self.bounds];
    bgView.backgroundColor = color;
    self.backgroundView = bgView;
}

Solution 20 - Iphone

I feel compelled to share my experience. I had this piece of code that worked fine with iOS 10 and iOS 11 headerView?.contentView.backgroundColor = .lightGray

Then I all of a sudden decided to to deploy the app for iOS 9 as there are some devices (iPad mini some older generation doesn't update to any OS beyond 9) - The only solution that worked for all iOS 9, 10 and 11 was to define a base view for the header that then contains all other header subviews, wire it up from storyboard and set the backgroundColor of that base view.

You will want to be mindful when wiring the outlet not to call it: backgroundView as there is already a property with that name in some superclass. I called mine containingView

Also when wiring the outlet control click on the view in Document Outline to make sure it's not wired up to file owner

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChunView Question on Stackoverflow
Solution 1 - IphoneSwiftArchitectView Answer on Stackoverflow
Solution 2 - IphoneMattView Answer on Stackoverflow
Solution 3 - IphonesashView Answer on Stackoverflow
Solution 4 - IphoneRudolf JView Answer on Stackoverflow
Solution 5 - IphoneAmJaView Answer on Stackoverflow
Solution 6 - IphoneEneko AlonsoView Answer on Stackoverflow
Solution 7 - IphoneChildhoodAndyView Answer on Stackoverflow
Solution 8 - IphoneHosnyView Answer on Stackoverflow
Solution 9 - IphoneJanView Answer on Stackoverflow
Solution 10 - IphonesamwizeView Answer on Stackoverflow
Solution 11 - IphoneVoloda2View Answer on Stackoverflow
Solution 12 - IphonetylyoView Answer on Stackoverflow
Solution 13 - Iphoneandrew54068View Answer on Stackoverflow
Solution 14 - IphoneEli BurkeView Answer on Stackoverflow
Solution 15 - Iphoneeli7ahView Answer on Stackoverflow
Solution 16 - IphoneShohinView Answer on Stackoverflow
Solution 17 - IphoneaasView Answer on Stackoverflow
Solution 18 - IphoneAlvin GeorgeView Answer on Stackoverflow
Solution 19 - Iphoneuser6434662View Answer on Stackoverflow
Solution 20 - IphoneAhmed KhedrView Answer on Stackoverflow