62

I have a array of headers that I use

let sectionHeaderTitleArray = ["test1","test2","test3]

and they are showed using

func tableView[tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.sectionHeaderTitleArray[section] as String
} 

Now all of this works fine but I would like to modify the background color of the headers so that they are more visible (Darker Color)

any idea if I can do this in a simple line or do I need to use a custom cell to create this

thanks

update

  //number of sections and names for the table

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return self.sectionHeaderTitleArray.count
    }

    func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return self.sectionHeaderTitleArray[section] as String
    }
    func tableView(tableView: UITableView, ViewForHeaderInSection section: Int) -> UIView? {
        return self.tableView.backgroundColor = UIColor.lightGrayColor()
    }
Jp4Real
  • 1,982
  • 4
  • 18
  • 33
  • 2
    possible duplicate of [UITableView - change section header color](http://stackoverflow.com/questions/813068/uitableview-change-section-header-color) – luk2302 May 14 '15 at 15:03
  • 1
    well you are returning a UIColor when it expects a UIView.. – Jack C May 14 '15 at 19:54
  • you need to set it with returnedView.backgroundColor = UIColor.lightGrayColor() where returnedView is the UIView you initialize in func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? – Jack C May 14 '15 at 19:55
  • thanks this changes the color correctly but my width and length settings are all setup in interface builder with autolayout.. how can I get this to adapt to the screen size? – Jp4Real May 14 '15 at 20:12
  • 1
    You will have to manually calculate the y value based on the data you are using, the x value can be 0, the width value will be UIScreen.mainScreen().bounds.size.width and the height will be around 10.0 (play around with this to your liking) – Jack C May 14 '15 at 20:36

17 Answers17

129

If you're using only titleForHeaderInSection :

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    (view as! UITableViewHeaderFooterView).contentView.backgroundColor = UIColor.black.withAlphaComponent(0.4)
    (view as! UITableViewHeaderFooterView).textLabel?.textColor = UIColor.white
}
Jovan Stankovic
  • 4,661
  • 4
  • 27
  • 16
  • I get a SIGABORT: Could not cast value of type 'UIView' (0x1b6464bc0) to 'UITableViewHeaderFooterView' – cdub Aug 14 '18 at 05:07
  • Hi, cdub. I've just tested it and it still works. Maybe you're returning some other view in viewForHeaderInSection callback? Anyway, you can insert - guard view is UITableViewHeaderFooterView else { print(view); return } check before setting color to see what's going on. – Jovan Stankovic Aug 15 '18 at 07:51
  • This works fine, but please do not force unwrap. You do not need to do that here at all. It just makes your code more prone to errors. – laka Apr 28 '20 at 20:16
40

Instead of using the

func tableView(_ tableView: UITableView,titleForHeaderInSection section: Int) -> String?

data source method, you can use the

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

delegate method and simply customize the UIView returned as you wish.

For example set the text of the UILabel textLabel to your desired value and the backgroundColor to the desired UIColor.

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let returnedView = UIView(frame: CGRectMake(x, y, width, height)) //set these values as necessary
    returnedView.backgroundColor = UIColor.lightGrayColor()

    let label = UILabel(frame: CGRectMake(labelX, labelY, labelWidth, labelHeight))
    label.text = self.sectionHeaderTitleArray[section]
    returnedView.addSubview(label)

    return returnedView
}

SWIFT 5

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            let returnedView = UIView(frame: CGRect(x: x, y: y, width: width, height: height)) //set these values as necessary
            returnedView.backgroundColor = .white

            let label = UILabel(frame: CGRect(x: x, y: y, width: width, height: height))

            label.text = self.sectionHeaderTitleArray[section]
            returnedView.addSubview(label)

            return returnedView
        }
mohsen
  • 4,698
  • 1
  • 33
  • 54
Jack C
  • 1,044
  • 2
  • 12
  • 22
17

You have to keep both

titleForHeaderInSection

AND

viewForHeaderInSection

Here is some working code in Swift 3

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return self.sectionHeaderTitleArray[section]
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let returnedView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 25))
    returnedView.backgroundColor = .lightGray

    let label = UILabel(frame: CGRect(x: 10, y: 7, width: view.frame.size.width, height: 25))
    label.text = self.sectionHeaderTitleArray[section]
    label.textColor = .black
    returnedView.addSubview(label)

    return returnedView
}
AMAN77
  • 6,218
  • 9
  • 45
  • 60
16

SWIFT 5

public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "headerId") as! CustomHeader
    let background = UIView(frame: view.bounds, background: .clear)
    header.backgroundView = background
    return header
}

SWIFT 4

Super easy, by setting header's view, contentView background color..

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
   let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "headerId") as! CustomHeader
   header.contentView.backgroundColor = AnyColor
   return header
}
emrcftci
  • 3,355
  • 3
  • 21
  • 35
MAGiGO
  • 599
  • 5
  • 13
  • This answer is a bit incomplete but seems to be the correct method. How would I go about creating the custom header view with a unique id in the first place? Currently I've seen a lot of methods online that just use a custom created cell that returns the content view of that cell. Would it be possible for you to expand a bit? – WBuck Jan 14 '18 at 12:23
  • I used https://stackoverflow.com/questions/36926612/swift-how-creating-custom-viewforheaderinsection-using-a-xib-file to fill in the blanks – WBuck Jan 14 '18 at 14:56
  • I find this answer by far the cleanest. – Junsu Kim Aug 22 '21 at 06:20
15

Swift 5 iOS 13:

//Remove 'override' if you don't override from UITableviewController
override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    guard let headerView = view as? UITableViewHeaderFooterView else { return }
    headerView.tintColor = .clear //use any color you want here .red, .black etc
}
Adriatik Gashi
  • 332
  • 4
  • 10
13

Swift 4.X

This is tested and working code.

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

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return "Total Count (41)"
}

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    view.tintColor = UIColor.lightGray
    let header = view as! UITableViewHeaderFooterView
    header.textLabel?.textColor = UIColor.darkGray
    header.textLabel?.font = UIFont.systemFont(ofSize: 14, weight: .medium)
}
Ashu
  • 3,373
  • 38
  • 34
4

Swift 3+

I used this:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 20))
    headerView.backgroundColor = .lightGray

    let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    label.text = stringValues[section]
    headerView.addSubview(label)
    label.leftAnchor.constraint(equalTo: headerView.leftAnchor).isActive = true
    label.rightAnchor.constraint(equalTo: headerView.rightAnchor).isActive = true
    label.centerYAnchor.constraint(equalTo: headerView.centerYAnchor).isActive = true
    label.heightAnchor.constraint(equalToConstant: 25).isActive = true

    return headerView

}
Dasoga
  • 5,489
  • 4
  • 33
  • 40
4

Swift 5

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

    guard let headerView = view as? UITableViewHeaderFooterView else { return }

    headerView.backgroundView?.backgroundColor = .red
}

And, if you want different header background (and/or text) colors for each section:

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

    guard let headerView = view as? UITableViewHeaderFooterView else { return }

    switch section {

    case 0:
        headerView.backgroundView?.backgroundColor = .red
        headerView.textLabel?.textColor = .white
    case 1:
        headerView.backgroundView?.backgroundColor = .green
        headerView.textLabel?.textColor = .white
    case 2:
        headerView.backgroundView?.backgroundColor = .yellow
        headerView.textLabel?.textColor = .black

        // etc

    default:
        return
    }
rbaldwin
  • 4,581
  • 27
  • 38
4

Swift5

Versión updated to iOS 11,12,13,14 with example

change background color and text color:

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    guard let tableView = view as? UITableViewHeaderFooterView else { return }
    tableView.textLabel?.textColor = UIColor.white
    tableView.contentView.backgroundColor = UIColor.black
}

Full example of viewcontroller:

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!
    private let array: [String] = ["ab","bc","cd","de","ef","fg","gh","hi","ij","jk"]
    let sectionHeaderTitleArray = ["test1","test2", "test3"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        if #available(iOS 11, *) {}
        else {
            self.edgesForExtendedLayout = []
        }
        configTableview()
    }
    
    private func configTableview() {
        tableView.registerCell(type: SyncCell.self)
        tableView.separatorColor = #colorLiteral(red: 0, green: 0.3066673801, blue: 1, alpha: 0.19)
        tableView.delegate = self
        tableView.dataSource = self
    }
}


extension ViewController: UITableViewDelegate {
    
    func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        guard let tableView = view as? UITableViewHeaderFooterView else { return }
        tableView.textLabel?.textColor = UIColor.white
        tableView.contentView.backgroundColor = UIColor.black
    }
    
    func tableView(_ tableView: UITableView,titleForHeaderInSection section: Int) -> String? {
        return sectionHeaderTitleArray[section]
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return 3
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return array.count
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 130
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("selected cell: \(indexPath)")
    }
}

extension ViewController: UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let item = array[indexPath.row]
        let cell = tableView.dequeueReusableCell(type: SyncCell.self, forIndexPath: indexPath)
        cell.configCell(text: item)
        cell.selectionStyle = .none
        return cell
    }
    
}
blacker
  • 768
  • 1
  • 10
  • 13
3

If you are using titleForHeaderInSection, then the easiest way is to add in viewDidLoad():

self.tableView.backgroundColor = UIColor.clear

For some reason, setting ClearColor for Background in the View section for the TableView in the Interface Builder doesnt always set it to transparent. But adding this one line in the code (for me at least) does.

Gefilte Fish
  • 1,600
  • 1
  • 18
  • 17
1

override viewForHeaderInSection and create UITableViewHeaderFooterView

 override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    var headrview = tableView.dequeueReusableHeaderFooterView(withIdentifier: "aaa")
    if headrview == nil {
        headrview = UITableViewHeaderFooterView(reuseIdentifier: "aaa")
    }
    let bview = UIView()
    bview.backgroundColor = Theme.current.navigationColor
    headrview?.backgroundView = bview
    headrview?.textLabel?.textColor = Theme.current.primaryTextColor
    return headrview
}
KMI
  • 258
  • 1
  • 10
0

Swift 4 solution.

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerView:UIView = UIView()
        headerView.backgroundColor = UIColor.lightGray
   return headerView
}
dscrown
  • 578
  • 1
  • 5
  • 21
0

If you have a custom header view, you can do it with contentView.backgroundColor.

GreatCornholio
  • 97
  • 2
  • 16
0

There is no need to use hacks such as willDisplayHeaderView method or others. Simply create your own class of UITableViewHeaderFooterView. Then in func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? return your created custom header view. You should change background color not directly for your header view but for contentView of your header view

let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: NotificationSettingsHeaderView.reuseIdentifier) as! NotificationSettingsHeaderView
headerView.label.text = dataSource.snapshot().sectionIdentifiers[section].title
headerView.contentView.backgroundColor = .red
return headerView

What's even better is to setup background color in init of your header view subclass

Vitalik Kizlov
  • 385
  • 5
  • 9
-1

This will change it for all the headers in your application :

UITableViewHeaderFooterView.appearance().backgroundColor = theme.subViewBackgroundColor
devjme
  • 684
  • 6
  • 12
-1

override or implement the function tableview will display

public func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        let headerView = (view as? UITableViewHeaderFooterView)
        headerView?.tintColor = .clear
    }
Muhammadjon
  • 190
  • 2
  • 11
-1

We can change the footer color in a section of tableView using the below code snippet.

  1. call the Method heightForFooterInSection

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

  2. call the method viewForFooterInSection

    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { let viw = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 5)) viw.backgroundColor = .white return viw }

Hope this will help you. This is a tested Code.

Karthick Ramesh
  • 1,451
  • 20
  • 30