带有在代码中绘制的自定义图像的 UITableViewCell

Posted

技术标签:

【中文标题】带有在代码中绘制的自定义图像的 UITableViewCell【英文标题】:UITableViewCell with custom image drawn in code 【发布时间】:2017-09-22 11:01:50 【问题描述】:

我有自己的自定义 UITableViewCell,我想在单元格类中为其绘制图像。我正在使用此代码:

- (UIImage *)drawImageWithIdentifier:(NSString *)currencyIdentifier inView:(UIImageView *)imageView 

NSLog(@"width: %f, height: %f", imageView.frame.size.width, imageView.frame.size.height);

ColorTable *colorTable = [[ColorTable alloc] init];

CGFloat contentInset = imageView.frame.size.height/4;

UIView *backgroundView = [[UIView alloc] initWithFrame:self.imageView.bounds];
backgroundView.backgroundColor = [colorTable colorWithID:currencyIdentifier];

UIImage *currencyImage = [UIImage imageNamed:@"dollar_icon.png"];

UIGraphicsBeginImageContextWithOptions(backgroundView.bounds.size, NO, [UIScreen mainScreen].scale);

[[UIBezierPath bezierPathWithRoundedRect:backgroundView.bounds cornerRadius:backgroundView.frame.size.height/2] addClip];

[backgroundView.layer renderInContext:UIGraphicsGetCurrentContext()];

CGFloat aspectRatio = currencyImage.size.width/currencyImage.size.height;

if (aspectRatio < 1) 
    //vertical image
    CGRect imageRect = CGRectMake(0, 0, (backgroundView.frame.size.height - 2*contentInset) *aspectRatio , backgroundView.frame.size.height - 2*contentInset);
    CGFloat pointX = (backgroundView.frame.size.width / 2) - (imageRect.size.width / 2);
    CGFloat pointY = (backgroundView.frame.size.height / 2) - (imageRect.size.height / 2);

    [currencyImage drawInRect:CGRectMake(pointX, pointY, imageRect.size.width, imageRect.size.height) blendMode:kCGBlendModeNormal alpha:0.1];

else if (aspectRatio > 1) 
    //horizontal image
    CGRect imageRect = CGRectMake(0, 0, (backgroundView.frame.size.height - 2*contentInset) *aspectRatio, backgroundView.frame.size.height - 2*contentInset);
    CGFloat pointX = (backgroundView.frame.size.width / 2) - (imageRect.size.width / 2);
    CGFloat pointY = (backgroundView.frame.size.height / 2) - (imageRect.size.height / 2);

    [currencyImage drawInRect:CGRectMake(pointX, pointY, imageRect.size.width, imageRect.size.height) blendMode:kCGBlendModeNormal alpha:0.1];

else if (aspectRatio == 1) 
    //square image
    CGRect imageRect = CGRectMake(0, 0, backgroundView.frame.size.height - 2*contentInset, backgroundView.frame.size.height - 2*contentInset);
    CGFloat pointX = (backgroundView.frame.size.width / 2) - (imageRect.size.width / 2);
    CGFloat pointY = (backgroundView.frame.size.height / 2) - (imageRect.size.height / 2);

    [currencyImage drawInRect:CGRectMake(pointX, pointY, imageRect.size.width, imageRect.size.height) blendMode:kCGBlendModeNormal alpha:0.1];


UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return finalImage;

在常规视图控制器中,它可以毫无问题地绘制图像,但是当我将此代码放入单元格类时,我收到类似 &lt;Error&gt;: CGContextAddPath: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. 的错误

我应该怎么做才能以编程方式成功为 UITableViewCell 绘制图像?

更新:

我发现这是我的错误,因为我使用self.imageView.bounds 作为backgroundView 的大小参数。我在 IB 中设计了我的单元格,我的单元格类使用self.currencyImage 作为UIImageView。错误不再出现,但我的self.currencyImage 仍然为空。

更新 2:

我终于找到了我犯的错误: 在我的 UITableViewCell 的.h 文件中,我有一个字符串属性,它应该作为currencyIdentifier 传递给- (UIImage *)drawImageWithIdentifier:(NSString *)currencyIdentifier inView:(UIImageView *)imageView。但似乎currencyIdentifier 为NULL,尽管我在TableViewController 中执行cell.currencyIdentifier = @"USD";

【问题讨论】:

避免在创建 tableviewcell 的地方进行任何繁重的处理......而不是将图像放入数组中,然后将它们传递给 tableviewcell。 @PulkitKumarSingh 请检查我的更新 ok....drawImageWithIdentifier...你什么时候调用这个函数? @PulkitKumarSingh 我在 [awakeFromNib] 方法中调用此函数。问题是我将currencyIdentifier 传递给单元格的类,但是当我调用currencyIdentifier 时,它似乎是NULL。该方法本身效果很好,但是没有currencyIdentifier就无法获取绘图的颜色和图像。 【参考方案1】:

此代码有问题

 [currencyImage drawInRect:CGRectMake(pointX, pointY, imageRect.size.width, imageRect.size.height) blendMode:kCGBlendModeNormal alpha:0.1];

不要在 UITableViewCell 中使用 draw rect

创建您的图像,然后将其作为子视图添加到单元格

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    
    cell.addsubview = yourImage 


    return cell
    

    Hope this helps.

    Try it out and let me know your result

【讨论】:

【参考方案2】:

不要在循环中调用 DrawRect。其昂贵的方法。

在单独的循环中创建图像,将它们添加到数组中并使用它。

static NSString *cellIdentifier = @"Cell";

 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

 if (cell == nil)
    
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
    

[cell addSubView:[self drawImageWithIdentifier:@"Identifier" inView:cell.contentView]];

 return cell

【讨论】:

以上是关于带有在代码中绘制的自定义图像的 UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章

带有图像的自定义 UIButton

黑莓中的自定义文本框

使用带有文本和图像的自定义适配器在列表视图中搜索

C ++ MFC,带有复选框的自定义网格,单选按钮[关闭]

无法清除 OnPaint 方法中的自定义控件

带有用于突出显示的图像的自定义 UITableViewCell