为什么drawRect留下图像的一部分?

dfdumaresq

这是我的情况:

我有一个包含餐厅列表的表,每个条目在使用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;
}
  • 表载荷,绘制4行

起始位置

  • 用户向下滚动;再画8行

在此处输入图片说明

  • 用户滚动回到顶部;Grace Market / Maple Pizza(第2行)的记分栏已更改。

在此处输入图片说明

在实现下面的@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];

(摘自https://stackoverflow.com/a/2746508/793607

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

PHP 删除一部分图像,留下透明空间

来自分类Dev

为什么这部分代码要先于另一部分执行?

来自分类Dev

提取图像的一部分以识别

来自分类Dev

(Android)如何显示图像的一部分?

来自分类Dev

使用CSS模糊图像的一部分

来自分类Dev

只旋转图像python的一部分

来自分类Dev

如何显示大图像的一部分?

来自分类Dev

播放图像堆栈的一部分

来自分类Dev

想要获得图像的一部分

来自分类Dev

在matlab中遮盖图像的一部分?

来自分类Dev

jQuery删除图像源的一部分

来自分类Dev

在Android中模糊图像的一部分

来自分类Dev

画布drawBitmap仅是图像的一部分

来自分类Dev

在Python中缩小图像的一部分

来自分类Dev

擦除Konvajs图像的一部分

来自分类Dev

如何淡化图像的一部分

来自分类Dev

使用 pyglet 使图像的一部分透明

来自分类Dev

在python中编辑图像的一部分

来自分类Dev

仅对图像的一部分应用腐蚀

来自分类Dev

为什么我要在特性上实现方法而不是特性的一部分?

来自分类Dev

为什么React会更新DOM的这一部分?

来自分类Dev

为什么runXXX不是MonadTrans定义的一部分?

来自分类Dev

为什么HTTP GET参数应该是url的一部分

来自分类Dev

为什么我不能在Java中复制数组的一部分?

来自分类Dev

为什么只记录我的json数据的一部分?

来自分类Dev

为什么排序方法是Collection而不是AbstractList的一部分?

来自分类Dev

为什么此tkinter菜单小部件的一部分没有显示?

来自分类Dev

为什么gsubfn省略了比赛的一部分?

来自分类Dev

为什么数组的维是其类型的一部分?