You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中使用Kingfisher修改ImageView着色异常问题求助

问题:横向CollectionView选中Cell时图片着色异常(背景覆盖)

我实现了一个横向CollectionView,选中特定Cell时需要修改ImageView的颜色。目前部分图片着色成功,但部分图片出现异常——着色效果表现为背景色直接覆盖整个图片区域,而非仅对图片内容着色。

原实现代码

图片着色函数

func imageWithColor(color1: UIColor) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
    color1.setFill()

    let context = UIGraphicsGetCurrentContext()! as CGContext
    context.translateBy(x: 0, y: self.size.height)
    context.scaleBy(x: 1.0, y: -1.0);
    context.setBlendMode(CGBlendMode.normal)

    let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect
    context.clip(to: rect, mask: self.cgImage!)
    context.fill(rect)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()! as UIImage
    UIGraphicsEndImageContext()

    return newImage
}

Kingfisher图片加载代码

imageProduct.kf.setImage(with: URL(string:"imageurl"), placeholder: nil) { result in
    self.imageProduct.image = self.categoryImg.image?.imageWithColor(color1: UIColor.green)
}

问题原因

  1. 混合模式错误:原函数使用CGBlendMode.normal混合模式,会让填充色直接覆盖整个画布,没有利用图片的Alpha通道限制着色范围,导致透明区域也被填充。
  2. Kingfisher逻辑错误:没有正确使用加载完成的网络图片,反而引用了categoryImg的图片,逻辑混乱且无法保证操作的是目标图片。

解决方案

修正后的图片着色函数

extension UIImage {
    func imageWithTintColor(_ color: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        defer { UIGraphicsEndImageContext() }
        
        color.setFill()
        // 使用sourceIn混合模式,仅对图片非透明区域填充颜色
        draw(in: CGRect(origin: .zero, size: size), blendMode: .sourceIn, alpha: 1.0)
        
        return UIGraphicsGetImageFromCurrentImageContext() ?? self
    }
}

这个实现简化了绘图逻辑,通过sourceIn混合模式自动保留图片的Alpha通道,确保着色仅作用于图片内容区域。

修正后的Kingfisher加载代码

imageProduct.kf.setImage(with: URL(string: "imageurl"), placeholder: nil) { [weak self] result in
    guard let self = self, case .success(let retrievedImage) = result else { return }
    // 对加载成功的网络图片直接着色
    let tintedImage = retrievedImage.imageWithTintColor(.green)
    self.imageProduct.image = tintedImage
}
  • 用weak self避免循环引用
  • 从Kingfisher的回调结果中正确获取加载完成的图片
  • 直接对目标图片进行着色,确保逻辑正确

内容的提问来源于stack exchange,提问作者Eslam Abotaleb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 14:05:26