1

I am using SVGKit library to render svg into image view. Svg is rendering perfectly but the issue is I am unable to fill the SVG colour. I found few examples in Objective C those are not helpful for me. Here I am using Swift5. Please find the attached Controller code. Thanks in advance.

Code:

let namSvgImgVar: SVGKImage = SVGKImage(named: "camera")
let namImjVar: UIImage = namSvgImgVar.uiImage
imageView.image = namImjVar

1 Answers1

2

I have created an extension for the same:

extension SVGKImage {

    // MARK:- Private Method(s)
    private func fillColorForSubLayer(layer: CALayer, color: UIColor, opacity: Float) {
        if layer is CAShapeLayer {
            let shapeLayer = layer as! CAShapeLayer
            shapeLayer.fillColor = color.cgColor
            shapeLayer.opacity = opacity
        }

        if let sublayers = layer.sublayers {
            for subLayer in sublayers {
                fillColorForSubLayer(layer: subLayer, color: color, opacity: opacity)
            }
        }
    }

    private func fillColorForOutter(layer: CALayer, color: UIColor, opacity: Float) {
        if let shapeLayer = layer.sublayers?.first as? CAShapeLayer {
            shapeLayer.fillColor = color.cgColor
            shapeLayer.opacity = opacity
        }
    }

    // MARK:- Public Method(s)
    func fillColor(color: UIColor, opacity: Float) {
        if let layer = caLayerTree {
            fillColorForSubLayer(layer: layer, color: color, opacity: opacity)
        }
    }

    func fillOutterLayerColor(color: UIColor, opacity: Float) {
        if let layer = caLayerTree {
            fillColorForOutter(layer: layer, color: color, opacity: opacity)
        }
    }
}

If your SVG image has only one layer to color use fillColor, or fillOutterLayerColor if there are multiple, you can modify it based on your need. This is how I use it:

static func getImage(imageName: String, fontSize size: CGSize, fillColor color: UIColor?, opacity: Float = 1.0) -> UIImage? {
    let svgImage: SVGKImage = SVGKImage(named: imageName)
    svgImage.size = size
    if let colorToFill = color {
       svgImage.fillColor(color: colorToFill, opacity: opacity)
    }

   return svgImage.uiImage
}
Sharad Chauhan
  • 4,821
  • 2
  • 25
  • 50
  • Sharad, Its looking good. in your above extension how can use this function (fillColorForOutter) for designer provided svg's? – Pavan Kumar Idapalapati Dec 28 '19 at 10:01
  • and one more thing, how much build size will increased for SVGKIT framework ? – Pavan Kumar Idapalapati Dec 28 '19 at 10:03
  • If you open SVG code you can see the layers. You can color layers based on your need. So outerLayer was for one of the few SVG’s which had multiple layers, you can use the first function only if there is only one layer. Your designer will understand. – Sharad Chauhan Dec 29 '19 at 13:46
  • I have not checked the size, as there are other pods too. So better you install and try by archiving it. – Sharad Chauhan Dec 29 '19 at 13:48
  • `fillColorForSubLayer(layer: CALayer, color: UIColor, opacity: Float)` This function is having CALayer type parameter then how can I pass it. It is inside the svg code right. – Pavan Kumar Idapalapati Dec 30 '19 at 05:44
  • @PavanKumarIdapalapati You don't have to make any changes unless the `fillColor` function fills the whole SVG image and not particular area. That particular are is layer. So layer in public function consists of all the layers inside SVG image, it's an array of sublayers which makes the SVG image, you can access the layers as per your need. – Sharad Chauhan Dec 30 '19 at 06:27
  • @PavanKumarIdapalapati You use only public methods, you don't have to pass any layer. SVGKImage has those layers. – Sharad Chauhan Dec 30 '19 at 06:29