如何访问tableView的标准viewForHeaderInSection视图?

6
我有一个带有单独部分的索引UITableView。我想为每个部分的标题视图使用不同的背景颜色。我知道我可以通过实现tableView:viewForHeaderInSection:(例如,参见question # 2898361)来完全自定义我的视图,但对我来说似乎这太麻烦了 - 标准视图看起来很好,我只需要更改其背景颜色。

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

3个回答

13

我几乎可以肯定你不能轻松地做到这一点。最近,我在我的开发帐户上使用了一次技术支持请求,询问如何修改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>

顺便说一下...这不是要模仿标准标题的外观 - 这只是一个例子。但我相信经过一些尝试和错误,您可以改变它以模仿标准标题,然后稍微改变颜色。


1
你的文本似乎缺少了一些东西.. #import 什么?可能是一些核心动画的东西吗? - Thorsten
哦,没错,使用CAGradientLayer需要QuartzCore库 - 我会在帖子中添加的。谢谢。 - bandejapaisa
它还缺少[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)]; - c roald
我确实说过“以下是我从一个项目中提取的一些代码 - 它被注释掉了”。但你是对的,那是正确的做法。我现在也喜欢使用CGRect宏:CGFloat width = CGRectGetWidth(tableView.bounds); - bandejapaisa

5
尽管其他答案正确地指出您无法访问默认视图以进行简单修改,但是如果您没有要自定义的特定部分标题,则可以从tableView:viewForHeaderInSection:返回nil,表视图将使用默认视图。 如果您只需要自定义某些标题,则此选项很有用。
出于某种原因,这是未记录的。

1

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接