带有核心图形的自定义表格视图单元

Posted

技术标签:

【中文标题】带有核心图形的自定义表格视图单元【英文标题】:Custom table view cell with Core graphics 【发布时间】:2013-10-24 08:32:24 【问题描述】:

我正在制作一个表格视图,用户可以在其中选择应用程序应在其中导入的日历,我的目的是制作类似于 Cal:https://www.dropbox.com/s/i980yr70j0vq0p1/foto.PNG

所以我创建了 TableViewController 并在 tableViewCellForRowAtIndexPath 中创建了我的自定义单元格:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *MyIdentifier = @"MyReuseIdentifier";
EKCalendar *calendar;
calendar = [theCalendarSyncEngine.calendars objectAtIndex:indexPath.row];
CalendarCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if(cell==nil)
    cell = [[CalendarCell alloc]initAndReuseIdentifier:MyIdentifier andIsChecked:FALSE andAColor:calendar.CGColor];

cell.title.text=calendar.title;
return cell;

CalendarCell 初始化方法:

- (id)initAndReuseIdentifier:(NSString *)reuseIdentifier andIsChecked:(BOOL)checked andAColor:(CGColorRef)color

self = [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
if (self) 
       // Initialization code
       theColor=color;
       positionFrame = CGRectMake(30,self.contentView.bounds.size.height/2-2.5,5,5);
       circle=[[CircleView alloc]initWithFrame:positionFrame andAColor:theColor];
       title = [[UILabel alloc] initWithFrame:CGRectMake(50.0, self.contentView.bounds.size.height/2-10, 230.0, 20.0)];
       title.backgroundColor = [UIColor clearColor];
       title.textAlignment = NSTextAlignmentLeft;
       title.textColor = [UIColor blackColor];
       title.font = [UIFont boldSystemFontOfSize:17.0];
       checkbox = [[UISelectionCheckbox alloc] initWithFrame:CGRectMake(270.0, self.contentView.bounds.size.height/2-10, 20, 20)];
       checkbox.backgroundColor = [UIColor clearColor];
       checkbox.checked = checked;
       [checkbox addTarget:self action:@selector(checkBoxTouched:)    forControlEvents:UIControlEventTouchUpInside];
       [self.contentView addSubview:circle];
       [self.contentView addSubview:circle];
       [self.contentView addSubview:title];
       [self.contentView addSubview:checkbox];
    
    return self;

日历单元格有一个 CircleView,它是一个带有日历颜色的圆圈、一个带有日历名称的标签和一个用于选择或不选择日历的复选框。

这是 CircleView 代码:

- (id)initWithFrame:(CGRect)frame andAColor:(CGColorRef)color

   self = [super initWithFrame:frame];
   if (self) 
       [self setBackgroundColor:[UIColor clearColor]];
       thisColor = color;
   
   return self;


- (void)drawRect:(CGRect)rect
   CGContextRef context= UIGraphicsGetCurrentContext();
   CGContextClearRect(context,rect);
   CGContextSetFillColorWithColor(context, thisColor);
   CGContextSetAlpha(context, 1);
   CGContextFillEllipseInRect(context, CGRectMake(0,0,self.frame.size.width,self.frame.size.height));
   CGContextSetStrokeColorWithColor(context, thisColor);

问题是 CircleView,当我显示 TableView 时,每个圆圈都有相同的颜色。我哪里错了?

更新

我按照提示修改代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
   static NSString *MyIdentifier = @"MyReuseIdentifier";
   EKCalendar *calendar;
   calendar = [theCalendarSyncEngine.calendars objectAtIndex:indexPath.row];
   CalendarCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
   if(cell==nil)
       cell = [[CalendarCell alloc]initAndReuseIdentifier:MyIdentifier andIsChecked:FALSE];
   
   cell.title.text=calendar.title;
   //UPDATE METHOD TO SET COLOR
   [cell setColor:calendar.CGColor];
   return cell;

CalendarCell里面的方法:

- (void)setColor:(CGColorRef)color

    [circle setColor:color];
    [circle setNeedsDisplay];

调用CircleView方法:

- (void)setColor:(CGColorRef)color

     thisColor=color;

【问题讨论】:

在 CalendarCell 初始化方法中检查颜色的值。是不是一直都一样?然后在 CircleView 的 init 方法中检查 thisColor。 这里的代码:"if (cell==nil)..." 如果你使用 storyboard/xib 将永远不会被调用,所以我猜你的 initAndReuseId 方法永远不会被调用。 我已经检查过了,颜色变了!所以我认为问题出在 TableView 方法上。 @CalinChitu 该方法每次调用一次单元格的数量,如果我不检查这个,每次单元格消失时都会重新创建。 【参考方案1】:

问题在于您在 init 方法中设置了单元格的颜色。这意味着如果您的单元格被重复使用,颜色将是单元格创建期间的颜色。

您应该将颜色集移出以下块

if(cell==nil)
cell = [[CalendarCell alloc]initAndReuseIdentifier:MyIdentifier andIsChecked:FALSE andAColor:calendar.CGColor];

在您的自定义单元格中创建一个设置颜色方法。并致电cell.setColor()calendar.CGColor

此外,您可能需要在您的 circleView 上调用 setNeedDisplay 以强制调用重绘重用单元格。

【讨论】:

我按照你的建议做了,情况已经改变,但在第一次加载时问题仍然存在,如果我滚动列表,消失的单元格会改变颜色。 现在我的代码看起来没问题。您可以检查在第一次加载时没有变量为零。抱歉,没看到还有什么问题

以上是关于带有核心图形的自定义表格视图单元的主要内容,如果未能解决你的问题,请参考以下文章

如何为 MkAnnotation View 自定义视图,就像表格视图的自定义单元格一样?

表格视图显示为空而不符合我的自定义单元格

带有故事板的自定义静态 TableView - 单元格背景

一个 UIViewController 中的自定义单元格 tableview 和默认 UITableView

使用自定义表格视图单元格中的故事板segue

表格视图中的自定义单元格未显示?