简体   繁体   中英

Transparent UITableViewHeaderFooterView

I'm trying to make a custom header view for this UITableView and I'd like it to be transparent.

My code...

Interface...

typedef void(^ActionBlock)();

@interface MyViewHeaderView : UITableViewHeaderFooterView

@property (nonatomic, strong) UIImageView *flagImageView;
@property (nonatomic, strong) UILabel *leagueNameLabel;

@property (nonatomic, copy) ActionBlock tapAction;

@end

Implementation...

#import "MyViewHeaderView.h"

@interface MyViewHeaderView ()

@end

@implementation MyViewHeaderView

- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithReuseIdentifier:reuseIdentifier];
    if (self) {
        // Add customisation here...

        // I have tried everything here...
        self.tintColor = [UIColor colorWithWhite:0.961 alpha:1.0];
        self.alpha = 0.5;

        // self.contentView.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.5];
        // self.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.5];
        // can't remember what else.
        // none of it makes it transparent. It sets the colour against
        // a white background. i.e. 50% transparent but with a white opaque background.
        // so I can't see the content of the table scrolling behind it.

        self.flagImageView = [[UIImageView alloc] init];
        self.flagImageView.image = [UIImage imageNamed:@"placeholder_flag"];
        [self.flagImageView setTranslatesAutoresizingMaskIntoConstraints:NO];
        [self.contentView addSubview:self.flagImageView];

        self.leagueNameLabel = [[UILabel alloc] init];
        [self.leagueNameLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
        [self.contentView addSubview:self.leagueNameLabel];

        UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewTapped)];
        tapGestureRecognizer.numberOfTapsRequired = 1;
        tapGestureRecognizer.numberOfTouchesRequired = 1;
        [self.contentView addGestureRecognizer:tapGestureRecognizer];

        [self setupConstraints];
    }
    return self;
}

- (void)setupConstraints
{
    // adding constraints...
}

- (void)viewTapped
{
    self.tapAction();
}

@end

In my UITableViewDelegate I'm loading the header like...

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    MyViewHeaderView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"HeaderView"];

    League *league = self.leagues[(NSUInteger) section];

    headerView.leagueNameLabel.text = league.name;
    headerView.tapAction = ^(){
        [self leagueTapped:league];
    };

    return headerView;
}

This is working fine, the header is showing properly. Just without transparency.

I'd like to have a header view like the standard view where you can see the table view content scrolling behind it.

Please can you let me know how to do this.

Make a view which has transparent background color and assign it to the UITableViewHeaderFooterView's backgroundView property.

class HeaderView: UITableViewHeaderFooterView{

    override
    init(reuseIdentifier: String?){
        super.init(reuseIdentifier: reuseIdentifier)
        self.backgroundView = UIView()
        self.backgroundView!.backgroundColor = UIColor.clearColor()
    }

    required
    init(coder: NSCoder){
        super.init(coder: coder)
    }

    override
    init(frame: CGRect){
        super.init(frame: frame)
    }
}

Please forgive my inability to use stackoverflow....

Here's how I managed to implement it, using both these UITableviewDelegate methods:

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
  if ([view isMemberOfClass:[UITableViewHeaderFooterView class]]) {
    ((UITableViewHeaderFooterView *)view).backgroundView.backgroundColor = [UIColor clearColor];
  }
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  UITableViewHeaderFooterView *feedHeaderView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"HeaderIdentifier"];

  //Other customizations

  return feedHeaderView;
}

Hope that helps, took me forever to figure out. It seems the backgroundView is not created in the init so the color cannot be overridden there.

UPDATE: apparantly, my previously suggested answer wasn't working anymore in iOS 13+, here's what I would get in console -

Setting the background color on UITableViewHeaderFooterView has been deprecated. Please set a custom UIView with your desired background color to the backgroundView property instead.

Further, looking at some comments here , setting tintColor to .clear did the trick.

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        view.tintColor = .clear
}

Have fun coding :)

On iOS 7, if you only want to force a transparent background on the default section header view, here is what you can do:

-(void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
    [[(UITableViewHeaderFooterView*)view backgroundView] setBackgroundColor:[UIColor clearColor]];
}

There is a way where you can still use your custom UITableViewHeaderFooterView and get a clear background always working without any "hack" and not just when scrolling the table to refresh the header.

Just add a custom background view with a clear background :) its as easy as that (tested on iOS 7.1)

Mine is this

- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithReuseIdentifier:reuseIdentifier];
    if (self) {
        NSArray* objects = [[NSBundle mainBundle] loadNibNamed:@"MessagesChatGroupSection"
                                                         owner:self
                                                       options:nil];
        UIView *nibView = [objects firstObject];
        self.frame = nibView.bounds;
        self.contentView.frame = nibView.bounds;
        [self.contentView addSubview:nibView];
        self.backgroundView = [[UIView alloc] initWithFrame:nibView.bounds];
        self.backgroundView.backgroundColor = [UIColor clearColor];
    }

    return self;
}

OK, from @schukin on Twitter.

I changed MyHeaderView to subclass UIView instead and set...

self.backgroundColor = [UIColor colorWithWhite:0.9 alpha:0.8];

and then in the delegate...

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    MyViewHeaderView *headerView = [[MyHeaderView alloc] initWithFrame:<a frame>];

    League *league = self.leagues[(NSUInteger) section];

    headerView.leagueNameLabel.text = league.name;
    headerView.tapAction = ^(){
        [self leagueTapped:league];
    };

    return headerView;
}

and this now works exactly as I want.

It seems UITableViewHeaderFooterView can't do what I'm looking for.

Thanks all.

The simplest way is:

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.contentView.backgroundColor = [UIColor clearColor];
        self.backgroundView = [UIView new]; // removes system background view
    }
    return self;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    static NSString *cellIdentifier = @"HeaderCell";

    UITableViewHeaderFooterView *cell = [tableView dequeueReusableHeaderFooterViewWithIdentifier:cellIdentifier];

    if (nil == cell)
    {
        cell = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:cellIdentifier];
        cell.backgroundView = [[UIImageView alloc] init]; //<--- why not?
    }
    return cell;
}

Maybe it helps...

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
{
    UIView *customTitleView = [[ [UIView alloc] initWithFrame:CGRectMake(10, 0, 300, 32)] autorelease];
    UILabel *titleLabel = [ [UILabel alloc] initWithFrame:CGRectMake(19, 0, 300, 32)];
    titleLabel.textColor = [UIColor darkGrayColor];
    titleLabel.shadowColor = [UIColor whiteColor];
    titleLabel.backgroundColor = [UIColor clearColor];
    [titleLabel setFont:[UIFont fontWithName: @"Helvetica-Bold" size: 17.0]];

    switch (section)
    {
        case 0:
            titleLabel.text = @"Title for section...";

            break;

        default:
            break;
    }

    [customTitleView addSubview:titleLabel];
    [titleLabel release];
    return customTitleView;

}

And for footer (with another frames and font size)...add the same code in

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section

The solution others have provided has been deprecated. This is the message I got from the other answers.

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

My solution is to to the following. Hope it helps someone. :-)

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
   UILabel *label = [[UILabel alloc] init];

   label.text = sectionNames[section];
   label.textAlignment = NSTextAlignmentCenter;
   label.textColor = [UIColor blackColor];
   label.backgroundColor = [UIColor clearColor];

   // Creates a thin border around the section header 
   label.layer.borderColor = [UIColor blackColor].CGColor;
   label.layer.borderWidth = 1;
   label.layer.cornerRadius = 16;

   return label; }

The simplest solution is to just set the backgroundColor of the cell.backgroundColor and the cell.contentView.backgroundColor

Swift 2.*: self.backgroundView?.backgroundColor = UIColor.clearColor() self.contentView.backgroundColor = UIColor.clearColor()

NOTE: Don't forget the backgroundColor of the textLabels!

cell.textLabel?.backgroundColor = UIColor.clearColor()

If you are just using footerview for spaces between sections but don't want it to hug bottom, this is a much simpler solution that also does not mess with deprecated footerView so you won't get those warnings.

Just hide it.

    override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
    let footerView = tableView.dequeueReusableHeaderFooterViewWithIdentifier(CellID.Footer.rawValue)
    footerView?.hidden = true
    return footerView
}

In iOS14 and later, you need to set the "backgroundConfiguration" property to .none (Swift) or [UIBackgroundConfiguration clearConfiguration] (Objective-C).

After check Apple developer doc, as it description

@interface UITableViewHeaderFooterView : UIView

The UITableViewHeaderFooterView class implements a reusable view that can be placed at the top or bottom of a table section. You use headers and footers to display additional information for that section. You can use this class as-is without subclassing in most cases. If you have custom content to display, create the subviews for your content and add them to the view in the contentView property. You can also assign an optional background view to the backgroundView property.

i tried this method, it works perfect for me

self.tintColor = [UIColor whiteColor];
UIView *backView = [[UIView alloc] initWithFrame:self.bounds];
backView.backgroundColor = [UIColor whiteColor];
self.backgroundView = backView;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM