简体   繁体   中英

Different background colors for the top and bottom of a UITableView

If you look at your Inbox in iPhone OS 3.0's Mail app, you'll see that swiping down displays a grayish background color above the UISearchBar.

Now, if you scroll down to the bottom of the table, you'll see that the background color at that end is white.

I can think of a couple ways of solving this problem, but they're pretty hacky:

  • Change the table view's background color depending on the current scrollOffset by overriding -scrollViewDidScroll:
  • Give the UITableView a clear background color and then set its superview's backgroundColor to a gradient pattern image.

Does anyone know what the "best practice" solution is for this problem? thanks.

There´s good answers at Light gray background in “bounce area”...

Where i found this codesnipet (slightly modified) that works great:

CGRect frame = self.tableView.bounds;
frame.origin.y = -frame.size.height;
UIView* grayView = [[UIView alloc] initWithFrame:frame];
grayView.backgroundColor = [UIColor grayColor];
[self.tableView addSubview:grayView];
[grayView release];

Swift:

var frame = self.tableView.bounds
frame.origin.y = -frame.size.height
let grayView = UIView(frame: frame)
grayView.backgroundColor = .gray
self.tableView.addSubview(grayView)

Swift 5.0+

Solution with an extension:

extension UITableView {

    func addTopBounceAreaView(color: UIColor = .white) {
        var frame = UIScreen.main.bounds
        frame.origin.y = -frame.size.height

        let view = UIView(frame: frame)
        view.backgroundColor = color

        self.addSubview(view)
    }
}

Usage: tableView.addTopBounceAreaView()

The easiest and most lightweight way to solve this problem is:

  1. Set the background color of the table view to whatever you want - in your case, white.
  2. Put the search bar view inside a container view. Set the table view's header view to this container view (instead of the search bar view itself, which is probably what you were doing previously).
  3. In that container view, add another subview with frame equal to a rect like (0, -480, 320, 480), and set the background color of that subview to whatever color you want - in your case, grayish.

That should be all you need to do. I just did this myself and achieved the look I wanted, exactly the same as the Mail app. Using scrollViewDidScroll is a major waste of CPU resources, and subclassing UITableView is super messy, IMO.

Set the tableFooterView to a view of 0 height and width that draws way outside its bounds. An easy way is to add a big subview to it:

self.tableView.tableFooterView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
UIView *bigFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 1000)];
bigFooterView.backgroundColor = [UIColor whiteColor];
bigFooterView.opaque = YES;
[self.tableView.tableFooterView addSubview:bigFooterView];
[bigFooterView release];

adjust [UIColor whiteColor] and the width of your bigFooterView accordingly (if your tableView can go horizontal, you'll want it to be wider than 320). This way at the top you will see whatever your table view background is, and on the bottom whatever you set this view's background to.

Courtesy of Erica Sadun:

- (void) scrollViewDidScroll: (UIScrollView *) sv
{
    float percent =  sv.contentOffset.y / sv.contentSize.height;
    percent = 0.5 + (MAX(MIN(1.0f, percent), 0.0f) / 2.0f);

    sv.backgroundColor = [UIColor colorWithRed:percent * 0.20392
                                         green:percent * 0.19607
                                          blue:percent * 0.61176 alpha: 1.0f];
}

and then here's the modified version I'm using:

- (void)scrollViewDidScroll:(UIScrollView *)sv
{
        UIColor *backgroundColor = nil;

        float percent = sv.contentOffset.y / sv.contentSize.height;
        percent = 0.5 + (MAX(MIN(1.0f, percent), 0.0f) / 2.0f);

        if (0.5f == percent)
        {
            backgroundColor = RGBCOLOR(233.0f, 235.0f, 237.0f);
        }
        else
        {
            CGFloat r = 233.0f * (1.0f - percent) + 255.0f * percent;
            CGFloat g = 235.0f * (1.0f - percent) + 255.0f * percent;
            CGFloat b = 237.0f * (1.0f - percent) + 255.0f * percent;
            backgroundColor = RGBCOLOR(r,g,b);
        }           
        sv.backgroundColor = backgroundColor;
}

Here is the Swift 3 version:

var frame = self.tableView.bounds
frame.origin.y = -frame.size.height
let view = UIView(frame: frame)
view.backgroundColor = .gray
self.tableView.addSubview(view)

This might not be a "best practice," but if you really want to do it like Apple, there's a private UITableView property called tableHeaderBackgroundColor . The grayish color is #e2e7ed .

You could put something like this in the -viewDidLoad method of a UITableViewController :

UIColor *grayishColor = [UIColor colorWithRed:226/255.0
                                        green:231/255.0
                                         blue:237/255.0 alpha:1.0];
[self.tableView setValue:grayishColor forKey:@"tableHeaderBackgroundColor"];

I solved this problem with the use of autolayouts. The solution works on different screen sizes and with orientation change.

   self.tableView.tableFooterView = UIView();

   if let tableFooterView = self.tableView.tableFooterView {
         let bigFooterView = UIView();
         bigFooterView.backgroundColor = UIColor.white;
         bigFooterView.isOpaque = true;
         tableFooterView.addSubview(bigFooterView);

         bigFooterView.translatesAutoresizingMaskIntoConstraints = false;

         tableFooterView.addConstraint(NSLayoutConstraint(item: bigFooterView, attribute: .trailing, relatedBy: .equal, toItem: tableFooterView, attribute: .trailing, multiplier: 1, constant: 0));
         tableFooterView.addConstraint(NSLayoutConstraint(item: bigFooterView, attribute: .leading, relatedBy: .equal, toItem: tableFooterView, attribute: .leading, multiplier: 1, constant: 0));
         tableFooterView.addConstraint(NSLayoutConstraint(item: bigFooterView, attribute: .top, relatedBy: .equal, toItem: tableFooterView, attribute: .top, multiplier: 1, constant: 0));
         tableFooterView.addConstraint(NSLayoutConstraint(item: bigFooterView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 1000));
   }

I have expanded the answer in Light gray background in “bounce area” of a UITableView to the bottom side as well. Hope this helps:)

CGRect topFrame = self.tableView.bounds;
topFrame.origin.y = -topFrame.size.height;
UIView* topView = [[UIView alloc] initWithFrame:topFrame];
topView.backgroundColor = [UIColor grayColor]; // change to any color you want
[self.tableView addSubview:topView];

CGRect bottomFrame = self.tableView.bounds;
bottomFrame.origin.y = self.tableView.contentSize.height;
UIView* bottomView = [[UIView alloc] initWithFrame:bottomFrame];
bottomView.backgroundColor = [UIColor grayColor]; // change to any color you want
[self.tableView addSubview:bottomView];

This is my solution:

    let topColor = UIColor.blue
    let bottomColor = UIColor.black

    self.tableView.backgroundColor = topColor
    self.tableView.tableFooterView = UIView(frame: CGRect.zero)
    let footerView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 1000))
    footerView.backgroundColor = bottomColor
    self.tableView.tableFooterView?.addSubview(footerView)

SwiftUI solution

 var body: some View {
        
        NavigationView {
            
            List(data, id: \.self) { data in
                Text("\(data)")
            }
            .onAppear {
                let headerView = UIView(frame: CGRect(x: 0, y: -400, width: UIScreen.main.bounds.width, height: 400.0))
                headerView.backgroundColor = .lightGray
                UITableView.appearance().addSubview(headerView)
            }
            .navigationBarTitle("Title", displayMode: .inline)
        }
    }

在此处输入图像描述


If you want a different background color below the List then add another UIView to change the backgroundView:

let backgroundView = UIView()
backgroundView.backgroundColor = .black
UITableView.appearance().backgroundView = backgroundView

在此处输入图像描述

You should look into using the tableHeaderView and tableFooterView properties of the UITableView .

I think you just want to set your cell's BG Color to white, and make the table's BG color the other (gray) color. Im not sure you'd have success trying to do that with transparent cells.

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