如何自定义UITableViewCell的背景色?


188

我想自定义UITableView中所有UITableViewCells的背景(也许还有边框)。到目前为止,我还无法自定义此内容,因此我有一堆默认的白色背景单元格。

iPhone SDK有办法做到这一点吗?

Answers:


193

您需要将单元格contentView的backgroundColor设置为您的颜色。如果您使用附件(例如公开箭头等),它们将显示为白色,因此您可能需要滚动自定义版本的附件。


108
例如myCell.contentView.backgroundColor = [UIColor greenColor];
2009年

1
vlado.grigorov的答案更加灵活-请参见William Denniss的答案
JoBu1324

3
例如,如何滚动自己的任何链接UITableViewCellAccessoryCheckmark?谢谢。
丹·罗森斯塔克2011年

6
要有时看到它,您需要设置:cell.textLabel.backgroundColor = [UIColor clearColor];
Evan Moran 2013年

205

这是我遇到的解决此问题的最有效方法,请使用willDisplayCell委托方法(使用cell.textLabel.text和/或cell.detailTextLabel.text时,文本标签背景也要处理白色) ):

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { ... }

调用此委托方法时,单元格的颜色是通过单元格而不是表格视图控制的,就像您使用时一样:

- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath { ... }

因此,在单元格委托方法的主体内,添加以下代码以替换单元格的颜色,或仅使用函数调用使表中的所有单元格具有相同的颜色。

if (indexPath.row % 2)
{
    [cell setBackgroundColor:[UIColor colorWithRed:.8 green:.8 blue:1 alpha:1]];
}
else [cell setBackgroundColor:[UIColor clearColor]];

在我的情况下,此解决方案效果很好...


这是一种更清洁的解决方案。其他大多数解决方案都需要子类化UITableViewCell。vlado.grigorov的解决方案对我不起作用。
罗尼·刘

确实,这是苹果自己根据我所看到的各种WWDC演示推荐的方法。
Mike Weller 2010年

尼斯-除了需要在列表顶部添加新行时。此方法使所有添加项具有相同的颜色。刷新确实可以修复它,但是花费了不必要的时间。昨天发现了……
JOM

除了使用Core Data之外,这似乎工作得很好。通过NSFetchedResultsController添加的新单元格似乎无法正确调用willDisplayCell。我无所适从使其工作起来……
radven 2012年

在Swift 2.0中设置背景色的等效行:cell.backgroundColor = UIColor.clearColor
kbpontius

104

这非常简单,因为OS 3.0只是在willDisplayCell方法中设置单元格的背景色。您不得在cellForRowAtIndexPath中设置颜色。

这适用于普通样式和分组样式:

码:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    cell.backgroundColor = [UIColor redColor];
}

PS:这里是willDisplayCell的文档摘录:

“表视图在使用单元格绘制行之前将消息发送给它的委托人,从而允许委托人在显示该对象之前对其进行自定义。此方法使委托人有机会覆盖之前设置的基于状态的属性。表格视图,例如选择和背景颜色。在委托返回之后,表格视图仅设置alpha和frame属性,然后仅在为行滑动时设置动画。”

我在colionel的这篇文章中找到了此信息。谢谢他!


3
这应该标记为正确答案,因为如果您有披露,您甚至都不需要做任何事情。指标
Ashish Awaghad 2011年

1
如果您想要与我的表格视图背景不同的单元格背景颜色,则此方法不起作用。
克里斯(Chris

对于组单元格,您可以在cellForRow上进行设置
Sharen Eayrs 2012年

58

到目前为止,我发现的最佳方法是设置单元格的背景视图并清除单元格子视图的背景。当然,无论带或不带配件,这仅在具有索引样式的表上看起来不错。

这是一个示例,其中单元格的背景显示为黄色:

UIView* backgroundView = [ [ [ UIView alloc ] initWithFrame:CGRectZero ] autorelease ];
backgroundView.backgroundColor = [ UIColor yellowColor ];
cell.backgroundView = backgroundView;
for ( UIView* view in cell.contentView.subviews ) 
{
    view.backgroundColor = [ UIColor clearColor ];
}

1
如果这样做,请确保也将opaque属性设置为NO。
莉莉·巴拉德

11
确实不建议使用透明的单元格控件。滚动性能将受到很大的影响,这就是Apple总是说要使用不透明控件的原因。
Mike Weller 2010年

3
在iOS 4.2及更高版本上,看起来不再需要循环。
Frank Schmitt

非常好。使用附件视图时效果完美!!
RyanG 2012年

19

只需将其放在您的UITableView委托类文件(.m)中:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell  forRowAtIndexPath:(NSIndexPath *)indexPath 
{
    UIColor *color = ((indexPath.row % 2) == 0) ? [UIColor colorWithRed:255.0/255 green:255.0/255 blue:145.0/255 alpha:1] : [UIColor clearColor];
    cell.backgroundColor = color;
}

7

我同意Seba的看法,我尝试在rowForIndexPath委托方法中设置交替行的颜色,但结果在3.2和4.2之间不一致。以下对我非常有用。

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

    if ((indexPath.row % 2) == 1) {
        cell.backgroundColor = UIColorFromRGB(0xEDEDED);
        cell.textLabel.backgroundColor = UIColorFromRGB(0xEDEDED);
        cell.selectionStyle = UITableViewCellSelectionStyleGray;
    }
    else
    {
        cell.backgroundColor = [UIColor whiteColor];
        cell.selectionStyle = UITableViewCellSelectionStyleGray;
    }

}

1
仍然不明白为什么在willDisplayCell中设置它会有所不同。无论我们是否执行正确,这都被称为?
Sharen Eayrs,2012年

6

在尝试了所有不同的解决方案之后,以下方法是最优雅的一种。在以下委托方法中更改颜色:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (...){
        cell.backgroundColor = [UIColor blueColor];
    } else {
        cell.backgroundColor = [UIColor whiteColor];
    }
}

4

vlado.grigorov有一些好的建议-最好的方法是创建一个backgroundView,并给它一种颜色,将其他所有内容设置为clearColor。另外,我认为这种方法是正确清除颜色的唯一方法(尝试使用他的示例-但设置为“ clearColor”而不是“ yellowColor”),这就是我要尝试的方法。


这种方法的优点是可以在Interface Builder中将颜色保留为设计时属性。一个较少的设计问题,需要开发人员进行交互。
whitneyland 2011年

1
cell.backgroundView = [[[UIView alloc] initWithFrame:cell.bounds]自动释放]; cell.backgroundView.backgroundColor = [UIColor redColor];
布莱恩

3

自定义表格视图单元格的背景最终成为一种“全有还是全无”的方法。很难以一种看起来并不奇怪的方式更改用于内容单元格背景的颜色或图像。

原因是单元格实际上跨越了视图的宽度。圆角只是其绘制样式的一部分,内容视图位于该区域中。

如果更改内容单元格的颜色,最终将在拐角处看到白色位。如果更改整个单元格的颜色,将有一个跨视图宽度的颜色块。

您绝对可以自定义单元格,但是它并不像您一开始想的那么简单。


1
这对于分组表中的单元格绝对是正确的,但普通表不必担心太多。没有装饰的无装饰单元应该看起来不错。
本·戈特利布

本-好点。我主要使用分组表,但是正如您提到的,普通表不会遭受任何这些问题的困扰。
安德鲁·格兰特

3

创建一个视图并将其设置为单元格的背景视图

UIView *lab = [[UIView alloc] initWithFrame:cell.frame];
            [lab setBackgroundColor:[UIColor grayColor]];
            cell.backgroundView = lab;
            [lab release];

3

扩展N.Berendt的答案-如果您要基于实际单元格数据对象中的某些状态设置单元格颜色,则在配置表格单元格的其余信息时,通常是在cellForRowAtIndexPath方法,您可以通过重写willDisplayCell方法以从内容视图背景色中设置单元格背景色来实现此目的-可以解决显示按钮背景等问题,但仍然可以在cellForRowAtIndexPath方法中控制颜色您正在执行所有其他单元格定制的地方。

因此:如果将此方法添加到表视图委托中:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    cell.backgroundColor = cell.contentView.backgroundColor;
}

然后,在您的cellForRowAtIndexPath方法中,您可以执行以下操作:

if (myCellDataObject.hasSomeStateThatMeansItShouldShowAsBlue) {
    cell.contentView.backgroundColor = [UIColor blueColor];
}

这样既省去了在willDisplayCell方法中再次检索数据对象的麻烦,又节省了在两个位置进行表单元的定制/自定义的地方-所有自定义项都可以在cellForRowAtIndexPath方法中进行。


3

创建图像以用作Photoshop或gimp的背景,并将其命名为myimage。然后,将此方法添加到tableViewController类中:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    UIImage *cellImage = [UIImage imageNamed:@"myimage.png"];//myimage is a 20x50 px with  gradient  color created with gimp
    UIImageView *cellView = [[UIImageView alloc] initWithImage:cellImage];
    cellView.contentMode = UIContentViewModeScaleToFill;
    cell.backgroundView = cellView;
    //set the background label to clear
    cell.titleLabel.backgroundColor= [UIColor clearColor];
}

如果您已将UITableView设置为在属性检查器中自定义,这也将起作用。


2

我的解决方案是将以下代码添加到cellForRowAtIndexPath事件:

UIView *solidColor = [cell viewWithTag:100];
if (!solidColor) {

    solidColor = [[UIView alloc] initWithFrame:cell.bounds];
    solidColor.tag = 100; //Big tag to access the view afterwards
    [cell addSubview:solidColor];
    [cell sendSubviewToBack:solidColor];
    [solidColor release];
}
solidColor.backgroundColor = [UIColor colorWithRed:254.0/255.0
                                             green:233.0/255.0
                                              blue:233.0/255.0
                                             alpha:1.0];

即使在使用公开按钮的情况下,它也可以在任何情况下工作,并且与我认为的cellWillShow事件相比,使您的逻辑更好地对cellForRowAtIndexPath中的单元格颜色状态进行操作。


1

子类化UITableViewCell并将其添加到实现中:

-(void)layoutSubviews
{
    [super layoutSubviews];
    self.backgroundColor = [UIColor blueColor];
}

1
    UIView *bg = [[UIView alloc] initWithFrame:cell.frame];
    bg.backgroundColor = [UIColor colorWithRed:175.0/255.0 green:220.0/255.0 blue:186.0/255.0 alpha:1]; 
    cell.backgroundView = bg;
    [bg release];

1

这将在最新的Xcode中工作。

-(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {
    cell.backgroundColor = [UIColor grayColor];
}

0

试试这个:

- (void)tableView:(UITableView *)tableView1 willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [cell setBackgroundColor:[UIColor clearColor]];
    tableView1.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @"Cream.jpg"]];
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.