这是我的情况:
我有一个包含餐厅列表的表,每个条目在使用drawRect绘制的记分栏中显示一段时间内的检查结果。
当用户向下然后向上滚动表格时,将显示带有黄色和红色正方形的记分栏,以前的记分栏将显示这些正方形。日期也被绘制到以前的记分栏中。
我的问题在于摆脱旧广场。不应在每次调用drawRect时将其擦除吗?
我在下面放置了三张图片,希望可以解释我的意思。
我认为表格行缓存自定义单元格不是问题吗?在此,一旦UITableCell建立单元出队,便会绘制记分条。单元格中的所有其他视图都是正确的,这使我认为问题在于drawRect无法清除图形上下文。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row < self.establishments.count) {
return [self establishmentCellForIndexPath:indexPath];
} else if (self._noResultsFound) {
return [self noResultsCell];
} else {
return [self loadingCell];
}
}
- (UITableViewCell *)establishmentCellForIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"EstablishmentCell";
DSFEstablishment *establishment = [self.establishments objectAtIndex:[indexPath row]];
DSFEstablishmentCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
[cell setEstablishment:establishment];
[cell updateCellContent];
return cell;
}
在updateCellContent期间,我们尝试清除旧的scorebarview(如果存在),但是代码从未找到DSFScorebarView类的其他子视图。最后,创建了scorebarView并将其添加到视图的子视图中。
- (void)updateCellContent {
NSLog(@"updateCellContent: %@", self.establishment.latestName);
self.name.text = self.establishment.latestName;
self.address.text = self.establishment.address;
self.type.text = self.establishment.latestType;
if (self.establishment.distance) {
self.distance.text = [NSString stringWithFormat:@"%.2f km", self.establishment.distance];
} else {
self.distance.text = @"";
}
// Clear out old scorebarView if exists
for (UIView *view in self.subviews) {
if ([view isKindOfClass:[DSFScorebarView class]]) {
NSLog(@">>>removeFromSuperview");
[view removeFromSuperview];
}
}
DSFScorebarView *scorebarView = [[DSFScorebarView alloc] initWithInspections:self.establishment.inspections];
[self addSubview:scorebarView];
}
使用initWithInspections中的drawRect绘制得分栏视图,并确保得分栏的长度不超过17个正方形(最近的检查)。每次检查都给定一个绿色=低|黄色=中等=高=的正方形,并在该正方形下方绘制年份。
我设置了self.clearsContextBeforeDrawing = YES,但是它不能解决问题。
// Custom init method
- (id)initWithInspections:(NSArray *)inspections {
CGRect scorebarFrame = CGRectMake(20, 38, 273, 22);
if ((self = [super initWithFrame:scorebarFrame])) {
self.inspections = inspections;
self.clearsContextBeforeDrawing = YES;
[self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
float xOffset = 0; // Keep track of position of next box -- start at 1
float yOffset = 0; // Fixed Y offset. Adjust to match shadows
NSString *previousYear = nil;
UIFont *yearFont = [UIFont fontWithName:@"PFTempestaFiveCompressed" size:8.0];
// take subset/slice of inspections. only the last 17, so it will fit on screen.
int inspections_count = (int)[self.inspections count];
int startIndex = inspections_count > 17 ? inspections_count - 17 - 1 : 0;
int subarrayLength = inspections_count > 17 ? 17 : inspections_count;
NSArray *inspectionsSlice = [self.inspections subarrayWithRange:NSMakeRange(startIndex, subarrayLength)];
for (id inspection in inspectionsSlice) {
// Top of box
NSMutableArray *pos0RGBA = [inspection colorForStatusAtPositionRGBA:0];
CGFloat topColor[] = ...
CGContextSetFillColor(ctx, topColor);
CGRect box_top = CGRectMake(xOffset, yOffset, kScoreBoxWidth, kScoreBoxHeight / 2);
CGContextAddRect(ctx, box_top);
CGContextFillPath(ctx);
// Bottom of box
NSMutableArray *pos1RGBA = [inspection colorForStatusAtPositionRGBA:1];
CGFloat bottomColor[] = ...
CGContextSetFillColor(ctx, bottomColor);
CGRect box_bottom = CGRectMake(xOffset, kScoreBoxHeight / 2 + yOffset, kScoreBoxWidth, kScoreBoxHeight / 2);
CGContextAddRect(ctx, box_bottom);
CGContextFillPath(ctx);
// Year Text
NSString *theYear = [inspection dateYear];
if (![theYear isEqualToString:previousYear]) {
CGFloat *yearColor = ...
CGContextSetFillColor(ctx, yearColor);
// +/- 1/2 adjustments are positioning tweaks
CGRect yearRect = CGRectMake(xOffset+1, yOffset+kScoreBoxHeight-2, kScoreBoxWidth+50, kScoreBoxHeight);
[theYear drawInRect:yearRect withFont:yearFont];
previousYear = theYear;
}
xOffset += kScoreBoxWidth + kScoreBoxGap;
}
在实现下面的@HaIR解决方案之后,点击表格行后,我得到了灰色背景的白色条。在将多余的宽度添加到“涂白”年线之后,这非常丑陋。
- (void)drawRect:(CGRect)rect {
...
CGFloat backgroundColour[] = {1.0, 1.0, 1.0, 1.0};
CGContextSetFillColor(ctx, backgroundColour);
CGRect fullBox = CGRectMake(xOffset, yOffset, kScoreBoxWidth * 17, 2 * (kScoreBoxHeight-2));
CGContextAddRect(ctx, fullBox);
CGContextFillPath(ctx);
for (id inspection in inspectionsSlice) {
...
您已经接管了DrawRect,因此它仅能完成您在dra中手动执行的操作
在其上方绘制任何内容之前,请用背景色填充整个条形区域。
您正在重新使用单元格,例如,您在第二个版本的Grace Market / Maple Plaza下显示了Turf Hotel Restaurant图。
CGContextSetFillColor(ctx, yourBackgroundColor);
CGRect fullBox = CGRectMake(xOffset, yOffset, kScoreBoxWidth * 17, kScoreBoxHeight);
CGContextAddRect(ctx, fullBox);
CGContextFillPath(ctx);
如果您只是清除单元格中的背景而不是背景颜色。然后:
CGContextClearRect(context, rect);
在DrawRect的开始处可能更合适。
修订:
仔细研究您的问题,根本问题是您没有找到并删除旧的DSFScoreboardView。也许您应该尝试通过子视图进行递归搜索。喜欢:
- (void)logViewHierarchy {
NSLog(@"%@", self);
for (UIView *subview in self.subviews) {
//look right here for your DSFScorebarView's
[subview logViewHierarchy];
}
}
@end
// In your implementation
[myView logViewHierarchy];
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句