22

How to implement (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section on iOS7 style like (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section works?

P.S. I just need to change a color of header's title of the UITableView and save it's style.

raed
  • 4,887
  • 4
  • 30
  • 49
Dmitry
  • 14,306
  • 23
  • 105
  • 189

6 Answers6

52

You can change the color a label inside a standard tableview header prior to rendering with willDisplayHeaderView. Will also work for both iOS6/iOS7.

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    if([view isKindOfClass:[UITableViewHeaderFooterView class]]){

        UITableViewHeaderFooterView *tableViewHeaderFooterView = (UITableViewHeaderFooterView *) view;
        tableViewHeaderFooterView.textLabel.textColor = [UIColor blueColor];
    }
}

For Reference

UITableViewHeaderFooterView: https://developer.apple.com/documentation/uikit/uitableviewheaderfooterview

UITableViewDelegate Protocol: https://developer.apple.com/documentation/uikit/uitableviewdelegate/1614905-tableview

Cœur
  • 37,241
  • 25
  • 195
  • 267
aumansoftware
  • 845
  • 8
  • 6
  • Great! Simplest way to change color (and font and size) without needing to create UIView. – Rick Oct 01 '13 at 07:02
8

If you need to change global color for both header and footer, then use appearance:

[[UILabel appearanceWhenContainedIn:[UITableViewHeaderFooterView class], nil] setTextColor:[UIColor redColor]];
onegray
  • 5,105
  • 1
  • 23
  • 29
6

Early in your view controller's lifecycle (eg, -viewDidLoad), register the class:

 [[self tableView] registerClass:[UITableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"headerFooterReuseIdentifier"];

Then, in your method: (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section deque a cell, style it however you wish, and return it:

 UIColor *titleColor = ... // Your color here.
 UITableViewHeaderFooterView *headerFoorterView = [[self tableView] dequeueReusableHeaderFooterViewWithIdentifier:@"headerFooterReuseIdentifier"];
 [[headerFooterView textLabel] setTextColor:titleColor];
 return headerFooterView;

And that's how you use a default implementation.

João Colaço
  • 1,202
  • 1
  • 14
  • 38
isaac
  • 4,867
  • 1
  • 21
  • 31
  • Isaac, thanks! But I can see only empty space with this code on iOS 7. What's wrong? – Dmitry Sep 15 '13 at 22:18
  • If you say, headerFooterView.backgroundColor = [UIColor greenColor]; do you see a green sectionView? You may also need to configure properties of that headerFooterView - start by setting a breakpoint in Xcode in your viewForHeaderInSection method, and seeing what the frame of the view is or if it's nil... – isaac Sep 15 '13 at 22:34
3

Not perfect but solution:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UILabel *label = [[UILabel alloc] init];
    label.textColor = [UIColor whiteColor];
    label.backgroundColor = [UIColor clearColor];
    if (<is_iOS7>) {
        label.text = [[NSString stringWithFormat:@"  %@", <title>] uppercaseString];
    } else {
        if (<is_iPad>) {
            label.text = [NSString stringWithFormat:@"          %@", <title>];
        } else {
            label.text = [NSString stringWithFormat:@"  %@", <title>];
        }
    }
    return label;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 38.f;
}
Dmitry
  • 14,306
  • 23
  • 105
  • 189
1

And @aumansoftware's answer is also the best way to add content into the standard header such as a button. Here is an example in Swift:

override func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    if (view.isKindOfClass(UITableViewHeaderFooterView)) {
        let headerView = view as UITableViewHeaderFooterView

        // Label
        headerView.textLabel.textColor = UIColor.blueColor()

        // New Button
        let addPeopleButton: UIButton = UIButton.buttonWithType(.ContactAdd) as UIButton
        addPeopleButton.addTarget(self, action: "showPeoplePicker:", forControlEvents: UIControlEvents.TouchUpInside)

        addPeopleButton.setTranslatesAutoresizingMaskIntoConstraints(false)
        headerView.addSubview(addPeopleButton)
        let right: NSLayoutConstraint = NSLayoutConstraint(item: addPeopleButton, attribute: NSLayoutAttribute.Right, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.Right, multiplier: 1.0, constant: -12)
        let vertical: NSLayoutConstraint = NSLayoutConstraint(item: addPeopleButton, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0)
        headerView.addConstraints([right, vertical])
    }
}
Collierton
  • 539
  • 5
  • 10
0

It works exactly as in iOS 6. Create a view (or just a label that covers the whole header) and style it according to your requirements.

Mundi
  • 79,884
  • 17
  • 117
  • 140
  • 1
    My requirements are **as it works by default**. For example, on iOS 7 it uses a slim font with upper case chars. How to do that? – Dmitry Sep 15 '13 at 21:57