Ios 如何在我的swift应用程序中设置绘制svg路径的动画?

Ios 如何在我的swift应用程序中设置绘制svg路径的动画?,ios,swift,svg,swift3,uibezierpath,Ios,Swift,Svg,Swift3,Uibezierpath,在我的ios swift应用程序中,我有SVG文件-它是一个地图标记的形状,现在我想用动画来绘制它。由于使用了pocketSVG,我成功地显示了图形。我的代码如下: @IBOutlet weak var mainLogoView: UIView! override func viewDidLoad() { super.viewDidLoad() let url = Bundle.main.url(forResource: "mainLogo", withExtension:

在我的ios swift应用程序中,我有
SVG
文件-它是一个地图标记的形状,现在我想用动画来绘制它。由于使用了
pocketSVG
,我成功地显示了图形。我的代码如下:

@IBOutlet weak var mainLogoView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()

    let url = Bundle.main.url(forResource: "mainLogo", withExtension: "svg")!

    //initialise a view that parses and renders an SVG file in the bundle:
    let svgImageView = SVGImageView.init(contentsOf: url)

    //scale the resulting image to fit the frame of the view, but
    //maintain its aspect ratio:
    svgImageView.contentMode = .scaleAspectFit

    //layout the view:
    svgImageView.translatesAutoresizingMaskIntoConstraints = false
    mainLogoView.addSubview(svgImageView)

    svgImageView.topAnchor.constraint(equalTo: mainLogoView.topAnchor).isActive = true
    svgImageView.leftAnchor.constraint(equalTo: mainLogoView.leftAnchor).isActive = true
    svgImageView.rightAnchor.constraint(equalTo: mainLogoView.rightAnchor).isActive = true
    svgImageView.bottomAnchor.constraint(equalTo: mainLogoView.bottomAnchor).isActive = true


    Timer.scheduledTimer(timeInterval: TimeInterval(2), target: self, selector: "functionHere", userInfo: nil, repeats: false)

}

func functionHere(){
    self.performSegue(withIdentifier: "MainSegue", sender: nil)
}
    func animateSVG(From startProportion: CGFloat, To endProportion: CGFloat, Duration duration: CFTimeInterval = animationDuration) {
        let animation = CABasicAnimation(keyPath: "strokeEnd")
        animation.duration = duration
        animation.fromValue = startProportion
        animation.toValue = endProportion
        animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
        svgLayer.strokeEnd = endProportion
        svgLayer.strokeStart = startProportion
        svgLayer.add(animation, forKey: "animateRing")
    }
因此,基本上在我的ViewController中,我在故事板上添加了一个名为
mainLogoView
视图,然后在那里显示SVG文件。现在,因为它是一个形状标记,非常类似于:我想画它-在2秒钟的时间里,我想画出圆圈周围的形状

我怎么做

====编辑:

按照Josh的建议,我注释掉了我的
viewdiload
中的大部分代码,取而代之的是:

let url = Bundle.main.url(forResource: "mainLogo", withExtension: "svg")!

    for path in SVGBezierPath.pathsFromSVG(at: url)
    {
        var layer:CAShapeLayer = CAShapeLayer()
        layer.path = path.cgPath
        layer.lineWidth = 4
        layer.strokeColor = orangeColor.cgColor
        layer.fillColor = UIColor.white.cgColor
        mainLogoView.addSubview(layer)
    }
但是现在最后一行抛出了一个错误

Cannot convert value of type 'CAShapeLayer' to expected argument type 'UIView'

另外,在编辑了我的代码之后,您能给我一个提示吗?我如何在这里使用Josh的方法?

而不是使用imageView方法将SVG转换为cgPath。将此路径指定给CAShapeLayer并将该形状层添加到视图中。可以按如下方式设置CAShapeLayer的endStroke动画:

@IBOutlet weak var mainLogoView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()

    let url = Bundle.main.url(forResource: "mainLogo", withExtension: "svg")!

    //initialise a view that parses and renders an SVG file in the bundle:
    let svgImageView = SVGImageView.init(contentsOf: url)

    //scale the resulting image to fit the frame of the view, but
    //maintain its aspect ratio:
    svgImageView.contentMode = .scaleAspectFit

    //layout the view:
    svgImageView.translatesAutoresizingMaskIntoConstraints = false
    mainLogoView.addSubview(svgImageView)

    svgImageView.topAnchor.constraint(equalTo: mainLogoView.topAnchor).isActive = true
    svgImageView.leftAnchor.constraint(equalTo: mainLogoView.leftAnchor).isActive = true
    svgImageView.rightAnchor.constraint(equalTo: mainLogoView.rightAnchor).isActive = true
    svgImageView.bottomAnchor.constraint(equalTo: mainLogoView.bottomAnchor).isActive = true


    Timer.scheduledTimer(timeInterval: TimeInterval(2), target: self, selector: "functionHere", userInfo: nil, repeats: false)

}

func functionHere(){
    self.performSegue(withIdentifier: "MainSegue", sender: nil)
}
    func animateSVG(From startProportion: CGFloat, To endProportion: CGFloat, Duration duration: CFTimeInterval = animationDuration) {
        let animation = CABasicAnimation(keyPath: "strokeEnd")
        animation.duration = duration
        animation.fromValue = startProportion
        animation.toValue = endProportion
        animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
        svgLayer.strokeEnd = endProportion
        svgLayer.strokeStart = startProportion
        svgLayer.add(animation, forKey: "animateRing")
    }

我确实遇到了同样的问题,这是我的解决方案。svgWidth、svgHeight是svg标记的宽度和高度

let url = Bundle.main.url(forResource: "mainLogo", withExtension: "svg")!

for path in SVGBezierPath.pathsFromSVG(at: url)
{
    var layer:CAShapeLayer = CAShapeLayer()
    layer.transform = CATransform3DMakeScale(CGFloat(mainLogoView.frame.width/svgWidth), CGFloat(mainLogoView.frame.height/svgHeight), 1)

    layer.path = path.cgPath
    layer.lineWidth = 4
    layer.strokeColor = orangeColor.cgColor
    layer.fillColor = UIColor.white.cgColor
    layer.transform = CATransform3DMakeScale(2, 2, 1)
    mainLogoView.layer.addSublayer(layer)
}

嗯,你能提供一个更详细的代码示例吗?我不确定这里的
strokeEnd
animateRing
是什么,我也不知道如何准确地将svg转换为cgPath:(您应该更改动画标识符,但无论如何它完全是任意的;它只是您动画的名称。strokeEnd是CAShapeLayer的一部分。请参阅文档:嗯,好的,您能给我一些示例,说明如何在代码中准确调用此函数吗?animateSVG(从:0到:1,持续时间:2)在两秒钟内将路径从路径长度的0%划到100%。请检查我原始问题的编辑部分好吗?层不是UIView,但UIView有层属性。您需要将shapeLayer作为子层添加到层中。MainLogView.layer.addSublayer(层)。此外,如果您有多个路径(如果链接它们,您可以这样做),动画将不正确。目的是您有一个路径,并且该路径中的所有点都按正确的顺序排列。谢谢,我最终成功地绘制了它:)我使用了:
for path in SVGBezierPath.pathsFromSVG(at:url){var layer:CAShapeLayer=CAShapeLayer()
您应该将SVG文件缩放到正确的大小。如果您需要可变大小,则需要在viewDidLayoutSubviews中计算它,并使用图层的.transform属性进行缩放。Josh,您能不能这样做并编写一段简单的代码?我怎么能做到这一点?我不知道它是如何工作的,也找不到可靠的教程:(