是否可以在 SwiftUI 中的某个路径上为视图设置动画 [英] Is it possible to animate view on a certain Path in SwiftUI

查看:23
本文介绍了是否可以在 SwiftUI 中的某个路径上为视图设置动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在 SwiftUI 中为特定路径上的视图设置动画.在 SwiftUI 之前,它只是设置其图层的路径属性的问题.我现在如何做类似的事情?

Is it possible to animate view on a certain Path in SwiftUI. Previous to SwiftUI it was just a matter of setting path property of its layer. How can I do something similar now?

编辑这是我如何使用 UIKit 完成的示例

EDIT Here is an example how i did it with UIKit

let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)

let animation = CAKeyframeAnimation(keyPath: #keyPath(CALayer.position))
    animation.duration = CFTimeInterval(duration)
    animation.repeatCount = 1
    animation.path = path.cgPath
    animation.isRemovedOnCompletion = true
    animation.fillMode = .forwards
    animation.timingFunction = CAMediaTimingFunction(name: .linear)

viewToAnimate.layer.add(animation, forKey: "someAnimationName")

推荐答案

是的,这是可能的.这是一个可能的方法的演示(粗糙,许多参数只是硬编码,但可以通过属性、构造函数、回调等进行配置)

Yes, it is possible. Here is a demo of possible approach (scratchy, many parameters just hardcoded, but the could be configured via properties, constructor, callbacks, etc.)

struct PathAnimatingView<Content>: UIViewRepresentable where Content: View {
    let path: Path
    let content: () -> Content

    func makeUIView(context: UIViewRepresentableContext<PathAnimatingView>) -> UIView {
        let view = UIView(frame: .zero)
        view.translatesAutoresizingMaskIntoConstraints = false
        view.layer.borderColor = UIColor.red.cgColor
        view.layer.borderWidth = 2.0

        let animation = CAKeyframeAnimation(keyPath: #keyPath(CALayer.position))
            animation.duration = CFTimeInterval(3)
            animation.repeatCount = 3
            animation.path = path.cgPath
            animation.isRemovedOnCompletion = false
            animation.fillMode = .forwards
            animation.timingFunction = CAMediaTimingFunction(name: .linear)

        let sub = UIHostingController(rootView: content())
        sub.view.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(sub.view)
        sub.view.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        sub.view.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true

        view.layer.add(animation, forKey: "someAnimationName")
        return view
    }

    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PathAnimatingView>) {
    }

    typealias UIViewType = UIView
}

struct TestAnimationByPath: View {
    var body: some View {
        VStack {
            PathAnimatingView(path: Circle().path(in: 
                              CGRect(x: 100, y: 100, width: 100, height: 100))) {
                Text("Hello, World!")
            }
        }
    }
}

这篇关于是否可以在 SwiftUI 中的某个路径上为视图设置动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆