20

I'm creating a UITableViewHeaderFooterView from a xib file, and almost everything is working properly.

The problem is that now when I try to change the background color (or if I had one configured in the xib), it will constantly output this message to the console:

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

This means I have two problems:

  • If I don't want to see that warning, I must get rid of the background color in the xib file.(This is undesirable because then it means my xib no longer reflects what the view will look like at runtime).
  • When I attempt to change the background color via code, I get the contentView.backgroundColor suggestion, but when I try to follow that suggestion, nothing happens. (This is because contentView is nil.)

Note: There is a similar question here, but that was mainly concerned with muting the message, not finding an alternative solution that resolves both problems above.

Update: To be clear, I want to continue using a xib file for the header view, and want to be able to call dequeueReusableHeaderFooterViewWithIdentifier: so that the table can be efficient in its management of the views.

Community
  • 1
  • 1
Senseful
  • 86,719
  • 67
  • 308
  • 465

7 Answers7

22

Here is the best way I've found to solve this:

  1. Reset the background color of your UITableViewHeaderFooterView to Default.
  2. Add a single view directly underneath the instance of your UITableViewHeaderFooterView, and call it Content View. (This is exactly what Apple does with a UITableViewCell, and we are just mimicking that structure.)
  3. You can now change the background color of the content view to be whatever you want in the xib file.
  4. Place any other views inside the Content View.
  5. Redefine the contentView property in an extension method, and add IBOutlet to its definition. (See code below.)
  6. Associate the property with the content view you created, just as you would with any IBOutlet.
  7. You can now change the background color using contentView.backgroundColor in code, just as the error message tells you to.

.h file:

@interface ABCHeaderView : UITableViewHeaderFooterView
@end

.m file:

@interface ABCHeaderView ()

@property (nonatomic, readwrite, retain) IBOutlet UIView *contentView;

@end

@implementation ABCHeaderView

@synthesize contentView;

@end

This hierarchy is consistent with Apple's documentation:

If you have custom content to display, create the subviews for your content and add them to the view in the contentView property.

Senseful
  • 86,719
  • 67
  • 308
  • 465
  • I used the following line for the outlet declaration instead @property (nonatomic, readonly, retain) IBOutlet UIView *contentView; Otherwise there is a warning. – Vladimír Slavík Mar 23 '15 at 15:17
10

To get rid of the warning you must not set the background color. The problem is when you creating TableHeader in such way, IB does not provide special object for that. Removing background color in source code will excelent solve described problem, just in some clicks.

  1. Found header .xib in Xcode
  2. Right click - Open As -> Source code
  3. Find color key: Cmd-F - "backgr"
  4. Remove it. In my case it was the line: <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
  5. Now you can change background like:

    override func awakeFromNib() {
    
        backgroundView = UIView()
        backgroundView?.backgroundColor = UIColor.whiteColor()
    }
    
Peter O.
  • 32,158
  • 14
  • 82
  • 96
HotJard
  • 4,598
  • 2
  • 36
  • 36
  • 1
    I had same warning on xcode console, I figure out with your answer, thanks for your detailed answer +1. – iamburak May 02 '16 at 16:08
  • Thank you for this. I thought I had to set the frame of the custom UIView, but no, this just plainly works :) – Lucas P. Apr 09 '18 at 13:48
5

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

This can happen if you design your header in a separate xib file and set the background of the main UIView in there.

To solve that, revert the UIView background color to the default color in InterfaceBuilder, and set the background color within the viewForHeaderInSection:section method.

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "CustomHeaderXibFileName") as! CustomHeader
    header.contentView.backgroundColor = UIColor.blueColor
}

As you see, we use header.contentView.backgroundColor and not header.backgroundColor (which is what the xib file was actually doing).

Arnaud
  • 17,268
  • 9
  • 65
  • 83
2

This works for me:

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

        UITableViewHeaderFooterView *headerView=(UITableViewHeaderFooterView *)view;
        [headerView.backgroundView setBackgroundColor:[[UIColor blackColor]colorWithAlphaComponent:0.4]];
    }
EFE
  • 3,732
  • 4
  • 22
  • 30
1

Try below extension code,

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

And assign background color like below,

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
   guard let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "CustomHeaderView") as? CustomHeaderView else {
      return UITableViewHeaderFooterView()
   }

   headerView.backgroundColor = .orange

   return headerView
}
Vicky Prajapati
  • 137
  • 1
  • 5
-1

Set the contentView.backgroundColor in the willAppear delegate callback:

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

or

- (void)tableView:(UITableView *)tableView
willDisplayFooterView:(UIView *)view
       forSection:(NSInteger)section
Jeff Holliday
  • 760
  • 6
  • 7
  • 1
    Unfortunately, this doesn't work because `contentView` is still `nil` in this method. This is most likely because the view is being created by a xib file. – Senseful Aug 04 '14 at 23:21
  • 1
    It's a subclass of UITableViewHeaderFooterView, which was created just like [the answer I linked to](http://stackoverflow.com/a/20073742/35690). – Senseful Aug 04 '14 at 23:39
  • Sounds radar worthy to me. – Jeff Holliday Aug 05 '14 at 14:50
-1

How about using code to create a custom Header and place it?

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

      UIView * myHeader = [[UIView alloc] initWithFrame: CGRectMake(0, 0, 320, 40)];
      [myHeader setBackgroundColor:[UIColor grayColor]];

      UILabel * TitleLabel = [[UILabel alloc] initWithFrame: CGRectMake(10, 5, 320, 20)];
      TitleLabel.text = @"My Title";

      [myHeader addSubview:TitleLabel];


      return myHeader;
}
c0deslayer
  • 515
  • 5
  • 7
  • 1
    I was hoping to create the view via a xib so I can design it in Interface Builder. I updated the question to reflect that fact. – Senseful Aug 04 '14 at 23:23