iosnstableheaderviewuitableview

How to set clear background for UITableView Header with opaque body


How do I make the background for a tableHeaderView clear, but keep the rest of the UITableView background opaque?

I'm using a transparent tableHeaderView for a paralax effect. The object behind the tableView is a longer than the clear tableHeaderView "window" so I can center the visible data. This works well for longer lists as I can use the tableView as a mask, but when I don't have enough cells in the table the background object displays below the cells.

Relevant code:

self.tableView.backgroundView = nil;
self.tableView.backgroundColor = [UIColor whiteColor];

UIView *tableHeaderView = [[UIView alloc] initWithFrame: CGRectMake(0.0, 0.0, 320.0, 250.0)];
tableHeaderView.backgroundColor = [UIColor clearColor];
self.tableView.tableHeaderView = tableHeaderView;

I've tried setting a background color for the tableView, but that makes the whole UITableView opaque (including the tableHeaderView), removing the "window" I have at the top.

Any ideas on how I can keep my transparent tableHeaderView while setting the body of the UITableView opaque?

Thanks!


Solution

  • After a couple days I was able to figure it out. The premise of the solution is to add a subview to the backgroundView of your table and change the subview's frame as you scroll.

    The relevant code in viewDidLoad:

    ...
    // Create the UIView that will become the tableView backgroundView
    UIView *tableViewBackground = [[UIView alloc] initWithFrame:self.tableView.frame];
    tableViewBackground.backgroundColor = [UIColor clearColor];
    
    // Create the opaque backgroundView and set the frame so that it starts below the headerView
    partialBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 250, 320.0, self.view.frame.size.height)];
    partialBackgroundView.backgroundColor = [UIColor redColor];
    
    // Add the partial background to the main background view and apply it to the tableView
    [tableViewBackground addSubview:solidTableBodyBackgroundView];
    self.tableView.backgroundView = tableViewBackground;
    ...
    

    And then as you scroll, you can update the "visible window" in scrollViewDidScroll:

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        CGFloat scrollOffset = scrollView.contentOffset.y;
        partialBackgroundView.frame = CGRectMake(0, 250 - scrollOffset, 320, self.view.frame.size.height);
        // Other parallax code for scrolling
    }
    

    There may be better ways of doing this, but I found this to be pretty simple and it worked well.