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.
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: tableView.register(UINib(nibName: "View", bundle: nil), forHeaderFooterViewReuseIdentifier: "header") Load with: 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 }
https://i.stack.imgur.com/2dvo5.gif
► Find this solution on GitHub and additional details on Swift Recipes.
You should either use myTableViewHeaderFooterView.tintColor
, or assign a custom background view to myTableViewHeaderFooterView.backgroundView
.
tintColor
not working on iOS7. I could change color only by assign custom view: myTableViewHeaderFooterView.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"myImage.png"]];
.tintColor
works if your view
background
is set to Default
color instead of System Background Default
color. But should not be using it as it is supposed to be tint color, not background color.
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];
Make sure you set the backgroundColor of the contentView
for your UITableViewHeaderFooterView
:
self.contentView.backgroundColor = [UIColor whiteColor];
Then it will work.
https://i.stack.imgur.com/DqtIq.png
https://i.stack.imgur.com/IyLTN.png
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:
https://i.stack.imgur.com/eT1Up.gif
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:
https://i.stack.imgur.com/DRISs.gif
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.
backgroundView = UIView()
and then backgroundColor = .clear
was the only working solution. Thank you.
https://i.stack.imgur.com/mcuFA.png
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
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.
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.
I tried with the appearanceWhenContainedIn chain, and it worked for me.
[[UIView appearanceWhenContainedIn:[UITableViewHeaderFooterView class], [UITableView class], nil]
setBackgroundColor: [UIColor.grayColor]];
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.
iOS 12, Swift 5. If you are willing (or trying!) to use an appearance proxy, the following solution works:
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
}
}
}
Set the appearance proxy at your desired granularity.
MySectionHeaderView.appearance().forceBackgroundColor = .red
or
MySectionHeaderView.appearance(whenContainedInInstancesOf: [MyOtherClass.self]).forceBackgroundColor = .red
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
2) In your custom header view class:
class MyHeaderView: UITableViewHeaderFooterView {
override func awakeFromNib() {
super.awakeFromNib()
backgroundColor = .red // <- here
}
}
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
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.
Swift:
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView {
var headerView: TableViewHeader = super.tableView(tableView, viewForHeaderInSection: section) as! TableViewHeader
headerView.backgroundView.backgroundColor = UIColor.redColor()
}
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;
}
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
Now since iOS 14 we've got UIBackgroundConfiguration for UITableViewHeaderFooterView.
To change the background color I'm doing the following:
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
if let headerView = view as? LeftMenuSectionHeader {
if var backgroundConfig = headerView.backgroundConfiguration {
backgroundConfig.backgroundColor = UIColor.clear
headerView.backgroundConfiguration = backgroundConfig
}
}
}
Success story sharing
view.BackgroundView = new UIView(view.Bounds) { BackgroundColor = UIColor.Clear };
Setting the background color on UITableViewHeaderFooterView has been deprecated. Please use contentView.backgroundColor instead.