UITableViewCell 在自定义单元格中具有备用背景颜色
Posted
技术标签:
【中文标题】UITableViewCell 在自定义单元格中具有备用背景颜色【英文标题】:UITableViewCell with alternate background color in customized cells 【发布时间】:2012-06-23 11:51:22 【问题描述】:我希望 UITableViewCells 的背景每显示两个单元格就具有不同的颜色,但是当我向下和向后滚动时,它们都会得到相同的颜色。知道我的单元格具有不同的 contentView 大小(根据它们的内容),我怎样才能获得这种效果?
#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 320.0f
#define CELL_CONTENT_MARGIN 20.0f
#define NAME_CELL_HEIGHT 20.0f
#import "CartCell.h"
@implementation CartCell
@synthesize nameLabel = _nameLabel;
@synthesize ingredientsLabel = _ingredientsLabel;
@synthesize myStore;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
myStore = [Store sharedStore];
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
self.nameLabel = nil;
self.ingredientsLabel = nil;
// SET "NAME" CELL
self.nameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[self.nameLabel setLineBreakMode:UILineBreakModeWordWrap];
[self.nameLabel setMinimumFontSize:FONT_SIZE];
[self.nameLabel setNumberOfLines:1];
[self.nameLabel setTag:1];
self.nameLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:18];
[self.nameLabel sizeToFit];
self.nameLabel.backgroundColor = [UIColor clearColor];
[[self contentView] addSubview:self.nameLabel];
// SET "INGREDIENTS" CELL
self.ingredientsLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[self.ingredientsLabel setLineBreakMode:UILineBreakModeWordWrap];
[self.ingredientsLabel setMinimumFontSize:FONT_SIZE];
[self.ingredientsLabel setNumberOfLines:0];
[self.ingredientsLabel setFont:[UIFont systemFontOfSize:FONT_SIZE]];
[self.ingredientsLabel setTag:2];
self.ingredientsLabel.backgroundColor = [UIColor clearColor];
[[self contentView] addSubview:self.ingredientsLabel];
if (myStore.cellBackgroundShouldBeLight == YES)
NSLog(@"clear [in] ? %@", myStore.cellBackgroundShouldBeLight ? @"Yes" : @"No");
self.contentView.backgroundColor = [[UIColor alloc]initWithRed:87.0/255.0 green:168.0/255.0 blue:229.0/255.0 alpha:1];
myStore.cellBackgroundShouldBeLight = NO;
else
NSLog(@"clear [in] ? %@", myStore.cellBackgroundShouldBeLight ? @"Yes" : @"No");
self.contentView.backgroundColor = [[UIColor alloc]initWithRed:187.0/255.0 green:268.0/255.0 blue:229.0/255.0 alpha:1];
myStore.cellBackgroundShouldBeLight = YES;
return self;
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
[super setSelected:selected animated:animated];
// Configure the view for the selected state
@end
更新:
我知道尝试按照建议在 cellForRowAtIndexPath 中设置它,但我得到了相同的结果:第一次向下滚动效果很好,但随后再次向上滚动会弄乱单元格的背景颜色。
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"CartCell";
CartCell *cell = (CartCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Recipes *info = [_fetchedResultsController objectAtIndexPath:indexPath];
if (cell == nil)
cell = [[CartCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// if (!cell.nameLabel)
// cell.nameLabel = (UILabel*)[cell viewWithTag:1];
// // cell.nameLabel = (UILabel*)[cell viewWithTag:1];
//
// if (!cell.ingredientsLabel)
// cell.ingredientsLabel = (UILabel*)[cell viewWithTag:2];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [info.ingredients sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
[cell.nameLabel setFrame:CGRectMake(10, 10, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), NAME_CELL_HEIGHT)];
[cell.ingredientsLabel setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN + NAME_CELL_HEIGHT, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
// SETTING TEXT CONTENT
cell.nameLabel.text = info.name;
cell.ingredientsLabel.text = info.ingredients;
// SETTING BACKGROUND COLOR
// UIView *lab = [[UIView alloc] initWithFrame:cell.frame];
// [lab setBackgroundColor:[UIColor blueColor]];
if (myStore.cellBackgroundShouldBeLight == YES)
NSLog(@"clear? %@", myStore.cellBackgroundShouldBeLight ? @"Yes" : @"No");
cell.contentView.backgroundColor = [[UIColor alloc]initWithRed:87.0/255.0 green:84.0/255.0 blue:229.0/255.0 alpha:1];
// cell.backgroundView = lab;
// ingredientsLabel.backgroundColor = [UIColor clearColor];
// nameLabel.backgroundColor = [[UIColor alloc]initWithRed:87.0/255.0 green:168.0/255.0 blue:229.0/255.0 alpha:1];
// [cell setBackgroundColor: [[UIColor alloc]initWithRed:87.0/255.0 green:168.0/255.0 blue:229.0/255.0 alpha:1]];
// [cell setBackgroundColor:[UIColor colorWithRed:.8 green:.8 blue:1 alpha:1]];
myStore.cellBackgroundShouldBeLight = NO;
else
// cell.contentView.tag = 2;
NSLog(@"clear? %@", myStore.cellBackgroundShouldBeLight ? @"Yes" : @"No");
cell.contentView.backgroundColor = [[UIColor alloc]initWithRed:187.0/255.0 green:184.0/255.0 blue:229.0/255.0 alpha:1];
myStore.cellBackgroundShouldBeLight = YES;
return cell;
【问题讨论】:
【参考方案1】:很简单,indexPath 告诉你你需要知道的一切。如果 indexPath.row 是偶数,则使用一种颜色。如果 indexPath.row 是奇数,请使用不同的颜色。
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
…
// SETTING BACKGROUND COLOR
// UIView *lab = [[UIView alloc] initWithFrame:cell.frame];
// [lab setBackgroundColor:[UIColor blueColor]];
if (indexPath.row % 2)
cell.contentView.backgroundColor = [[[UIColor alloc]initWithRed:87.0/255.0 green:84.0/255.0 blue:229.0/255.0 alpha:1] autorelease];
else
cell.contentView.backgroundColor = [[[UIColor alloc]initWithRed:187.0/255.0 green:184.0/255.0 blue:229.0/255.0 alpha:1] autorelease];
…
return cell;
您的方法存在问题,因为盲目假设单元格将被要求交替成对是一个错误的假设。 tableView 可以选择任何顺序的单元格。在您的示例中,我相信可以按如下方式要求单元格。首先,要求 0、1、...、9。接下来,向下滚动并获取 10、11 和 12。此时,0、1 和 2 已离开屏幕。您向上滚动并要求输入 2,但是哦,不,您的模型是奇数交替,所以您得到了错误的颜色。
【讨论】:
这将导致相当大的泄漏。 @max_ 如果他使用 ARC,则不会,但我会添加自动释放。 @jeffery_thomas,UIColor
有一个自动释放的方法,你应该改用它。 [UIColor colorWithRed...];
@max_ 是的,我知道,我个人从不使用 alloc/init 作为颜色,但这不是原始海报使用的。我尽量坚持使用原始代码。我希望人们只看到所需的更改。
还有 - 您可能需要执行 cell.textLabel.backgroundColor = [UIColor clearColor] 才能看到背景颜色。【参考方案2】:
使用-willDisplayCell
方法。
- (void)tableView: (UITableView *)tableView willDisplayCell: (UITableViewCell *)cell forRowAtIndexPath: (NSIndexPath *)indexPath
if (indexPath.row %2) //change the "%2" depending on how many cells you want alternating.
UIColor *altCellColor = [UIColor colorWithRed:255/255.0 green:237/255.0 blue:227/255.0 alpha:1.0]; //this can be changed, at the moment it sets the background color to red.
cell.backgroundColor = altCellColor;
else if (indexPath.row %2)
UIColor *altCellColor2 = [UIColor colorWithRed:1 green:1 blue:1 alpha:1.0]; //this can be changed, at the moment it sets the background color to white.
cell.backgroundColor = altCellColor2;
【讨论】:
【参考方案3】:更改单元格背景颜色的适当位置是“cellForRowAtIndexPath:
”方法,其中单元格数据被填写并返回到表格视图。
执行此操作的一种方法是:当数据进入单元格时,根据您所在的行更改背景颜色。
【讨论】:
【参考方案4】:将颜色放在 cellForRowAtIndexPath 上:不要在自定义单元格上设置。
【讨论】:
【参考方案5】:看看我用什么来定制我的桌子
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
#if USE_CUSTOM_DRAWING
const NSInteger TOP_LABEL_TAG = 1001;
const NSInteger BOTTOM_LABEL_TAG = 1002;
UILabel *topLabel;
UILabel *bottomLabel;
#endif
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
//
// Create the cell.
//
cell =
[[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]
autorelease];
#if USE_CUSTOM_DRAWING
UIImage *indicatorImage = [UIImage imageNamed:@"indicator.png"];
cell.accessoryView =
[[[UIImageView alloc]
initWithImage:indicatorImage]
autorelease];
const CGFloat LABEL_HEIGHT = 20;
UIImage *image = [UIImage imageNamed:@"imageA.png"];
//
// Create the label for the top row of text
//
topLabel =
[[[UILabel alloc]
initWithFrame:
CGRectMake(
image.size.width + 2.0 * cell.indentationWidth,
0.5 * (aTableView.rowHeight - 2 * LABEL_HEIGHT),
aTableView.bounds.size.width -
image.size.width - 4.0 * cell.indentationWidth
- indicatorImage.size.width,
LABEL_HEIGHT)]
autorelease];
[cell.contentView addSubview:topLabel];
//
// Configure the properties for the text that are the same on every row
//
topLabel.tag = TOP_LABEL_TAG;
topLabel.backgroundColor = [UIColor clearColor];
topLabel.textColor = [UIColor colorWithRed:0.25 green:0.0 blue:0.0 alpha:1.0];
topLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];
topLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
//
// Create the label for the top row of text
//
bottomLabel =
[[[UILabel alloc]
initWithFrame:
CGRectMake(
image.size.width + 2.0 * cell.indentationWidth,
0.5 * (aTableView.rowHeight - 2 * LABEL_HEIGHT) + LABEL_HEIGHT,
aTableView.bounds.size.width -
image.size.width - 4.0 * cell.indentationWidth
- indicatorImage.size.width,
LABEL_HEIGHT)]
autorelease];
[cell.contentView addSubview:bottomLabel];
//
// Configure the properties for the text that are the same on every row
//
bottomLabel.tag = BOTTOM_LABEL_TAG;
bottomLabel.backgroundColor = [UIColor clearColor];
bottomLabel.textColor = [UIColor colorWithRed:0.25 green:0.0 blue:0.0 alpha:1.0];
bottomLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];
bottomLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize] - 2];
//
// Create a background image view.
//
cell.backgroundView =
[[[UIImageView alloc] init] autorelease];
cell.selectedBackgroundView =
[[[UIImageView alloc] init] autorelease];
#endif
#if USE_CUSTOM_DRAWING
else
for (UIView *sub in [cell.contentView subviews])
// if([sub class] == [UITableViewCellContentView class])
NSLog(@"this is uilabel %@",[sub class]);
topLabel = (UILabel *)[cell viewWithTag:TOP_LABEL_TAG];
bottomLabel = (UILabel *)[cell viewWithTag:BOTTOM_LABEL_TAG];
topLabel.text = [NSString stringWithFormat:@"Cell at row %ld.", [indexPath row]];
bottomLabel.text = [NSString stringWithFormat:@"Some other information.", [indexPath row]];
//
// Set the background and selected background images for the text.
// Since we will round the corners at the top and bottom of sections, we
// need to conditionally choose the images based on the row index and the
// number of rows in the section.
//
UIImage *rowBackground;
UIImage *selectionBackground;
NSInteger sectionRows = [aTableView numberOfRowsInSection:[indexPath section]];
NSInteger row = [indexPath row];
if (row == 0 && row == sectionRows - 1)
rowBackground = [UIImage imageNamed:@"topAndBottomRow.png"];
selectionBackground = [UIImage imageNamed:@"topAndBottomRowSelected.png"];
else if (row == 0)
rowBackground = [UIImage imageNamed:@"topRow.png"];
selectionBackground = [UIImage imageNamed:@"topRowSelected.png"];
else if (row == sectionRows - 1)
rowBackground = [UIImage imageNamed:@"bottomRow.png"];
selectionBackground = [UIImage imageNamed:@"bottomRowSelected.png"];
else
rowBackground = [UIImage imageNamed:@"middleRow.png"];
selectionBackground = [UIImage imageNamed:@"middleRowSelected.png"];
((UIImageView *)cell.backgroundView).image = rowBackground;
((UIImageView *)cell.selectedBackgroundView).image = selectionBackground;
// cell.backgroundView.backgroundColor = [UIColor colorWithPatternImage:rowBackground];
// cell.selectedBackgroundView.backgroundColor = [UIColor colorWithPatternImage:selectionBackground];
//
// Here I set an image based on the row. This is just to have something
// colorful to show on each row.
//
if ((row % 3) == 0)
cell.imageView.image = [UIImage imageNamed:@"imageA.png"];
else if ((row % 3) == 1)
cell.imageView.image = [UIImage imageNamed:@"imageB.png"];
else
cell.imageView.image = [UIImage imageNamed:@"imageC.png"];
#else
cell.text = [NSString stringWithFormat:@"Cell at row %ld.", [indexPath row]];
#endif
return cell;
毕竟#import
行
#define USE_CUSTOM_DRAWING 1
【讨论】:
【参考方案6】:标题##更改交替颜色的最简单方法
if(indexPath.row%2)
cell.backgroundColor=[UIColor nameUrColor] //brownColor, yellowColor, blueColor
else
cell.backgroundColor=[UIColor nameAnotherColor]
【讨论】:
【参考方案7】:if(cell.contentView)
[cell.nameLbl setFont:[UIFont systemFontOfSize:24]];
int red_value = arc4random() % 210;
int green_value = arc4random() % 210;
int blue_value = arc4random() % 210;
cell.contentView.backgroundColor = [UIColor colorWithRed:red_value/255.0 green:green_value/255.0 blue:blue_value/255.0 alpha:0.6];
【讨论】:
以上是关于UITableViewCell 在自定义单元格中具有备用背景颜色的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 AutoLayouts 在自定义单元格中正确显示 2 个 UITextFields?
在自定义单元格中调整 iOS 7.1 中的 UILabel 大小