【问题标题】:Different background colors for the top and bottom of a UITableViewUITableView 顶部和底部的不同背景颜色
【发布时间】:2009-07-11 20:37:24
【问题描述】:

如果您在 iPhone OS 3.0 的邮件应用中查看收件箱,您会看到向下滑动会在 UISearchBar 上方显示灰色背景。

现在,如果您向下滚动到表格底部,您会看到那一端的背景颜色是白色。

我可以想出几种方法来解决这个问题,但它们都很老套:

  • 根据当前的 scrollOffset 通过覆盖 -scrollViewDidScroll 来更改表格视图的背景颜色:
  • 为 UITableView 赋予清晰的背景颜色,然后将其父视图的 backgroundColor 设置为渐变图案图像。

有谁知道这个问题的“最佳实践”解决方案是什么?谢谢。

【问题讨论】:

    标签: iphone uitableview


    【解决方案1】:

    Light gray background in “bounce area”... 有很好的答案

    我在哪里发现这个代码片段(稍作修改)效果很好:

    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];
    

    斯威夫特:

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

    【讨论】:

    • 如果您还使用 UIRefreshControl,那么您需要将 grayView 设置为透明,如下所示: grayView.alpha = .5;
    • 这似乎比公认的答案更容易、更笼统。
    • 这很好用。在 Swift 3 中也是这样:d.pr/n/JPkG+
    • @Daniel 另一个对我有用的选项是增加刷新控件层的 zPosition。
    • UIRefreshControl 一起使用时的另一个选项是将视图发送到视图堆栈的底部self.tableView.insertSubview(grayView, at: 0) 而不是self.tableView.addSubview(grayView)
    【解决方案2】:

    Swift 5.0+

    带扩展的解决方案:

    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)
        }
    }
    

    用法:tableView.addTopBounceAreaView()

    【讨论】:

      【解决方案3】:

      解决这个问题最简单、最轻量的方法是:

      1. 将表格视图的背景颜色设置为您想要的任何颜色 - 在您的情况下为白色。
      2. 将搜索栏视图放入容器视图中。将表格视图的标题视图设置为此容器视图(而不是搜索栏视图本身,这可能是您之前所做的)。
      3. 在该容器视图中,添加另一个子视图,其框架等于 (0, -480, 320, 480) 等矩形,并将该子视图的背景颜色设置为您想要的任何颜色 - 在您的情况下为灰色。

      这应该就是您需要做的所有事情。我自己做了这个,实现了我想要的外观,与邮件应用程序完全相同。使用scrollViewDidScroll主要是浪费CPU资源,继承UITableView超级麻烦,IMO。

      【讨论】:

        【解决方案4】:

        将 tableFooterView 设置为高度和宽度为 0 的视图,该视图在其边界之外绘制。一个简单的方法是给它添加一个大的子视图:

        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];
        

        相应地调整 [UIColor whiteColor] 和 bigFooterView 的宽度(如果你的 tableView 可以水平,你会希望它比 320 更宽)。这样,您将在顶部看到您的表格视图背景是什么,而在底部您将这个视图的背景设置为什么。

        【讨论】:

        • 非常不错的 hack。零大小的页脚不会增加滚动范围,但您仍然可以从过度绘制中获得背景颜色。在 iOS 7 中运行良好。为了更好地支持多方向和设备,我使用 [[UIScreen mainScreen] bounds].size.height 而不是 320 常量。
        • @WilliamDenniss,使用 mainScreen 的边界可能并不总是有效,例如,如果您的表格视图位于 iPad 上的主/详细视图中。最好将宽度设置为表格的宽度:[[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.tableView.frame), 1000)]; 或更新viewDidLayoutSubviews中的宽度
        • 是的,我在底部找到了最好的解决方案。
        • @alper 如果您使用 tableHeaderView 并将 y 值设置为 -1000,这也适用于顶部
        • 除其他答案外,这适用于使用 iOS 11 的大标题
        【解决方案5】:

        由 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];
        }
        

        然后这是我正在使用的修改版本:

        - (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;
        }
        

        【讨论】:

        • 我有同样的问题,但是通过运行这段代码,我看不到预期的结果。你能解释一下它是如何为你工作的吗?
        • 我发现我不需要调整百分比,我只是根据初始百分比计算决定颜色。浮动百分比 = sv.contentOffset.y / sv.contentSize.height; if (percent
        【解决方案6】:

        这里是 Swift 3 版本:

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

        【讨论】:

          【解决方案7】:

          这可能不是“最佳实践”,但如果您真的想像 Apple 那样做,有一个名为 tableHeaderBackgroundColor 的私有 UITableView 属性。浅灰色为#e2e7ed

          您可以在UITableViewController-viewDidLoad 方法中添加这样的内容:

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

          【讨论】:

          • 谢谢,我刚刚打开 rdar://problem/7334912 要求 Apple 在 UITableView 上公开此属性。
          • @AaronBrethorst 这件事后来被曝光了吗?
          • 不,这仍然是私有的,但是有一个比任何现有答案都更好的解决方案。基本上,子类UITableView 并覆盖-layoutSubviews 以在表格视图的contentOffset 指示它被拉下时在适当的空间显示自定义视图。
          【解决方案8】:

          我通过使用自动布局解决了这个问题。该解决方案适用于不同的屏幕尺寸和方向变化。

             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));
             }
          

          【讨论】:

            【解决方案9】:

            我也将Light gray background in “bounce area” of a UITableView 中的答案扩展到了底部。希望这会有所帮助:)

            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];
            

            【讨论】:

            • 不幸的是,如果您希望颜色清晰,这不起作用。然后它会回到浅灰色背景色。
            【解决方案10】:

            这是我的解决方案:

                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)
            

            【讨论】:

              【解决方案11】:

              SwiftUI 解决方案

               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)
                      }
                  }
              


              如果您想在 List 下方使用不同的背景颜色,请添加另一个 UIView 以更改 backgroundView:

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

              【讨论】:

                【解决方案12】:

                您应该考虑使用UITableViewtableHeaderViewtableFooterView 属性。

                【讨论】:

                • 这并没有真正解决我的问题。这两个视图具有固定的高度。去看看你的 iPhone 上的邮件。看看 UISearchBar 上方的背景颜色与表格底部的背景颜色有何不同?
                【解决方案13】:

                我认为您只想将单元格的 BG 颜色设置为白色,并将表格的 BG 颜色设置为其他(灰色)颜色。我不确定您是否会成功尝试使用透明单元格来做到这一点。

                【讨论】:

                  猜你喜欢
                  • 2021-09-09
                  • 1970-01-01
                  • 1970-01-01
                  • 2022-10-14
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-10-13
                  • 1970-01-01
                  • 2021-12-10
                  相关资源
                  最近更新 更多