【问题标题】:How can I access the standard viewForHeaderInSection for a tableView?如何访问 tableView 的标准 viewForHeaderInSection?
【发布时间】:2011-09-12 19:12:33
【问题描述】:

我有一个带有各个部分的索引 UITableView。我想为每个部分的标题视图使用不同的背景颜色。我知道我可以通过实现 tableView:viewForHeaderInSection:(例如,参见 question # 2898361)来完全滚动自己的视图,但这对我来说似乎“工作量太大” - 标准视图看起来不错,我只需要更改它的背景颜色。

但是如何访问这个标准视图呢?我不能使用[super tableView:viewForHeaderInSection:],因为这是实现协议的问题,而不是继承问题。有什么其他方法可以获得标准视图?

【问题讨论】:

    标签: ios uitableview


    【解决方案1】:

    我几乎可以肯定你不能轻易做到这一点。我最近在我的开发帐户上使用了我的技术支持请求之一,询问如何更改 UITableView 部分的背景和边框。苹果工程师告诉我,这确实不是一件容易的事情,即使你做到了,也可能会影响性能。他还给我指出了 cocoawithlove 和一篇关于编辑 uitableviews 的文章:

    http://cocoawithlove.com/2009/08/adding-shadow-effects-to-uitableview.html

    确实,创建自己的标题并不费力。下面是我从我的一个项目中提取的一些代码 - 它已被注释掉,因此可能无法立即工作 - 但你可以明白:

     - (CAGradientLayer *) greyGradient {
        CAGradientLayer *gradient = [CAGradientLayer layer];
        gradient.startPoint = CGPointMake(0.5, 0.0);
        gradient.endPoint = CGPointMake(0.5, 1.0);
    
        UIColor *color1 = [UIColor colorWithRed:255.0f/255.0f green:255.0f/255.0f blue:255.0f/255.0f alpha:1.0];
        UIColor *color2 = [UIColor colorWithRed:240.0f/255.0f green:240.0f/255.0f blue:240.0f/255.0f alpha:1.0];
    
        [gradient setColors:[NSArray arrayWithObjects:(id)color1.CGColor, (id)color2.CGColor, nil]];
        return gradient;
    }
    
    - (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
        CGFloat width = CGRectGetWidth(tableView.bounds); 
        CGFloat height = [self tableView:tableView heightForHeaderInSection:section];
        UIView *container = [[[UIView alloc] initWithFrame:CGRectMake(0,0,width,height)] autorelease];
        container.layer.borderColor = [UIColor grayColor].CGColor;
        container.layer.borderWidth = 1.0f;
        CAGradientLayer *gradient = [self greyGradient];
        gradient.frame = container.bounds;
        [container.layer addSublayer:gradient];
    
        UILabel *headerLabel = [[[UILabel alloc] initWithFrame:CGRectMake(12,0,width,height)] autorelease];
        headerLabel.backgroundColor = [UIColor clearColor];
        headerLabel.font= [UIFont boldSystemFontOfSize:19.0f];
        headerLabel.shadowOffset = CGSizeMake(1, 1);
        headerLabel.textColor = [UIColor whiteColor];
        headerLabel.shadowColor = [UIColor darkGrayColor];
        NSString *title = [self tableView:tableView titleForHeaderInSection:section];
        headerLabel.text = title;
        return container;
    }
    

    请务必

    #import <QuartzCore/QuartzCore.h>
    

    顺便说一句...这不应该模仿标准标题的外观 - 它只是一个示例。但我敢肯定,通过一些试验和错误,您可以改变它以模仿标准颜色,然后稍微改变颜色。

    【讨论】:

    • 您的文本中似乎缺少某些内容.. #import 什么?可能是一些核心动画的东西?
    • 哦,是的,它是用于使用 CAGradientLayer 的 QuartzCore - 我会将其添加到帖子中。谢谢
    • 它也缺少[container addSubview:headerLabel],如果你这样做真的更好:CGFloat width = tableView.bounds.size.width; CGFloat height = [self tableView:tableView heightForHeaderInSection:section]; UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,width,height)];
    • 我确实说过“下面是我从我的一个项目中提取的一些代码 - 它已被注释掉”。但你是对的,这是正确的方法。我现在也喜欢使用 CGRect 宏:CGFloat width = CGRectGetWidth(tableView.bounds);
    【解决方案2】:

    尽管其他答案正确指出您无法访问默认视图以对其进行简单修改,但如果您没有为特定节标题自定义任何内容,您可以从 tableView:viewForHeaderInSection: 返回 nil 并且表格视图将使用默认视图。

    如果您只需要自定义一些标题,这将很有帮助。

    无论出于何种原因,这是undocumented

    【讨论】:

      【解决方案3】:

      @bandejapalsa 解决方案存在一个问题:前一个单元格的分隔符在此实现中仍然可见,因为它不在默认的 iOS sectionHeaderView 上。我找到的解决方案是使用 CALayer 并将其偏移 1 个像素。图片需要比视图框架本身高 1pix。

      // Create the view for the header
      CGRect aFrame =CGRectMake(0, 0, tableView.contentSize.width, IMIUICustomisation.sectionHeaderViewHeight);
      UIView * aView = [[UIView alloc] initWithFrame:aFrame];
      aView.backgroundColor = UIColor.clearColor;
      
      // Create a stretchable image for the background that emulates the default gradient, only in green
      UIImage *viewBackgroundImage = [[UIImage imageNamed:@"greenheader.png"] stretchableImageWithLeftCapWidth:12 topCapHeight:0];
      
      // Cannot set this image directly as the background of the cell because
      // the background needs to be offset by 1pix at the top to cover the previous cell border (Alex Deplov's requirement ^_^)
      CALayer *backgroungLayer = [CALayer layer];
      
      backgroungLayer.frame = CGRectMake(0, -1, tableView.contentSize.width, IMIUICustomisation.sectionHeaderViewHeight+1);
      backgroungLayer.contents = (id) viewBackgroundImage.CGImage;
      backgroungLayer.masksToBounds = NO;
      backgroungLayer.opacity = 0.9;
      [aView.layer addSublayer:backgroungLayer];
      
      // Take care of the section title now
      UILabel *aTitle = [[UILabel alloc] initWithFrame: CGRectMake(10, 0, aView.bounds.size.width-10, aView.bounds.size.height)];
      aTitle.text = [delegate tableView:tableView titleForHeaderInSection:section];
      aTitle.backgroundColor = UIColor.clearColor;
      aTitle.font = [UIFont boldSystemFontOfSize:18];
      aTitle.textColor = UIColor.whiteColor;
      
      // Text shadow
      aTitle.layer.shadowOffset = CGSizeMake(0, 1);
      aTitle.layer.shadowRadius = .2;
      aTitle.layer.masksToBounds = NO;
      aTitle.layer.shadowOpacity = 0.5;
      aTitle.layer.shadowColor = IMIUICustomisation.selectedElementTextShadowColor.CGColor;
      [aView addSubview:aTitle];
      
      return aView;
      

      【讨论】:

        猜你喜欢
        • 2023-03-24
        • 2017-07-11
        • 2019-10-21
        • 2015-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多