Search code examples
swiftuicalayer

How could I display the entire CALayer content in the SwiftUI?


My code is very simple as follow:

import PocketSVG
import SwiftUI

struct SVGImage: UIViewRepresentable {
    var SVGName: String?
    var tintStrokeColor: CGColor?
    var tintFillColor: CGColor?

    func makeUIView(context: Context) -> UIView {
        return UIView()
    }

    func updateUIView(_ view: UIView, context: Context) {
        let svgURL = Bundle.main.url(forResource: "tiger", withExtension: "svg")!
        let paths = SVGBezierPath.pathsFromSVG(at: svgURL)
        let layer = CALayer()
        for path in paths {
            let shapeLayer = CAShapeLayer()
            shapeLayer.path = path.cgPath

            if let any = path.svgAttributes["stroke"] {
                shapeLayer.strokeColor = (any as! CGColor)
            }

            if let any = path.svgAttributes["fill"] {
                shapeLayer.fillColor = (any as! CGColor)
            }

            layer.addSublayer(shapeLayer)
        }

        layer.contentsGravity = CALayerContentsGravity.resizeAspectFill
        layer.contentsScale = UIScreen.main.scale
        view.layer.addSublayer(layer)
    }
}

struct SVGImage_Previews: PreviewProvider {
    static var previews: some View {
        SVGImage()
    }
}

But it doesn't display the entire image in the View, and it only display part.

I also set the CALayerContentsGravity.resizeAspectFill and UIScreen.main.scale, but it does not take effect.


Solution

  • This is a relatively easy fix:

    layer.position = svgView.center

    And also add the layer to a UIView like the following:

    import PocketSVG
    import SwiftUI
    
    struct SVGImage: UIViewRepresentable {
        var SVGName: String?
        var tintStrokeColor: CGColor?
        var tintFillColor: CGColor?
    
        func makeUIView(context: Context) -> UIView {
            let svgView = UIView(frame: UIScreen.main.bounds)
            svgView.contentMode = .scaleAspectFit
    
            let svgURL = Bundle.main.url(forResource: "tiger", withExtension: "svg")!
            let paths = SVGBezierPath.pathsFromSVG(at: svgURL)
            let layer = CALayer()
    
            for path in paths {
                let shapeLayer = CAShapeLayer()
                shapeLayer.path = path.cgPath
    
                if let any = path.svgAttributes["stroke"] {
                    shapeLayer.strokeColor = (any as! CGColor)
                }
    
                if let any = path.svgAttributes["fill"] {
                    shapeLayer.fillColor = (any as! CGColor)
                }
    
                layer.addSublayer(shapeLayer)
            }
    
            layer.position = svgView.center
            svgView.layer.addSublayer(layer)
    
            return svgView
        }
    
        func updateUIView(_ view: UIView, context: Context) {
    
        }
    }
    
    struct SVGImage_Previews: PreviewProvider {
        static var previews: some View {
            SVGImage()
        }
    }