在Swift中如何为同一个SVG图标同时设置两种不同的颜色
结论
这个需求完全可以实现,不需要复杂开发,只需要对SVG源文件做简单的分层处理即可,下面是具体要求和实现方案:
SVG源文件要求
不需要特殊设计,只需要设计师导出SVG时满足两个条件:
- 箭头、圆形两个元素保留为独立的路径,不要合并为单个路径
- 给两个路径分别设置唯一的
id属性,比如圆形路径id设为circle,箭头路径id设为arrow,导出时勾选保留标识/图层名称的选项即可
实现方案
你原来的代码使用.alwaysTemplate渲染模式只能给整图设置统一色调,属于单模板色渲染逻辑,要实现双色可以选择以下任意一种方案:
方案1:手动分层渲染(无第三方依赖,iOS13+兼容)
你可以直接用文本编辑器打开SVG源文件,分别复制两个<path>标签的d属性值(就是路径字符串),然后用CoreGraphics分层绘制:
// 扩展:将SVG路径字符串转换为UIBezierPath extension UIBezierPath { convenience init?(svgPathString: String) { guard let cgPath = CGPathCreateWithSVGString(svgPathString as CFString, nil, nil) else { return nil } self.init(cgPath: cgPath) } } // 绘制双色图标 let iconSize = CGSize(width: 24, height: 24) // 替换为你的图标实际尺寸 let renderer = UIGraphicsImageRenderer(size: iconSize) let dualTintImage = renderer.image { context in // 绘制底层圆形,填充蓝色 if let circlePath = UIBezierPath(svgPathString: "这里替换为你复制的圆形路径d属性值") { UIColor.systemBlue.setFill() circlePath.fill() } // 绘制上层箭头,填充红色 if let arrowPath = UIBezierPath(svgPathString: "这里替换为你复制的箭头路径d属性值") { UIColor.systemRed.setFill() arrowPath.fill() } } playImageView.image = dualTintImage
方案2:使用SVGKit分层改色(开发效率更高)
如果图标需要频繁改色或者路径复杂,可以用SVGKit库直接根据ID获取图层修改填充色:
import SVGKit let svgIcon = SVGKImage(named: "play") // 修改圆形图层颜色 if let circleLayer = svgIcon?.caLayerTree.sublayers?.first(where: { $0.name == "circle" }) as? CAShapeLayer { circleLayer.fillColor = UIColor.systemBlue.cgColor } // 修改箭头图层颜色 if let arrowLayer = svgIcon?.caLayerTree.sublayers?.first(where: { $0.name == "arrow" }) as? CAShapeLayer { arrowLayer.fillColor = UIColor.systemRed.cgColor } playImageView.image = svgIcon?.uiImage
注:你原始代码里的
UIIImage多写了一个I,注意修正为UIImage避免编译报错。
内容的提问来源于stack exchange,提问作者SimpleApp
相关产品推荐
相关产品推荐

