SwiftUI |动画此路径形状

Posted

技术标签:

【中文标题】SwiftUI |动画此路径形状【英文标题】:SwiftUI | Animate This Path Shape 【发布时间】:2020-10-20 13:32:40 【问题描述】:

我有以下情况:

我想用自定义动画翻转这个形状。不知道怎么形容。

每当我点击箭头时,它应该转换到另一个箭头。无需翻转、旋转等,只需简单变换即可。

如果不够准确,欢迎评论!

演示代码

struct ContentView: View 
    
    @State private var change = false
    
    private let arrowWidth: CGFloat = 80
    
    
    var body: some View 
        Path  path in
            path.move(to: .zero)
            path.addLine(to: CGPoint(x: arrowWidth/2, y: change ? -20 : 20))
            path.move(to: CGPoint(x: arrowWidth/2, y: change ? -20 : 20))
            path.addLine(to: CGPoint(x: arrowWidth, y: 0))
        
        .stroke(style: StrokeStyle(lineWidth: 12, lineCap: .round))
        .frame(width: arrowWidth)
        .foregroundColor(.green)
        .animation(.default)
        .onTapGesture  change.toggle() 
        .padding(.top, 300)
    

你现在可以看到它没有动画。我不知道该怎么做。

非常感谢任何帮助。谢谢!

注意:我不能用两个圆角矩形 + 简单地旋转来做到这一点,因为我有一个不透明动画,这使得重叠可见。

【问题讨论】:

【参考方案1】:

这是可能的方法 - 将路径移动到自定义形状并将更改的参数作为动画属性。使用 Xcode 12 / ios 14 测试

struct MyArrow: Shape 
    var width: CGFloat
    var offset: CGFloat
    
    var animatableData: CGFloat 
        get  offset 
        set  offset = newValue 
    
    
    func path(in rect: CGRect) -> Path 
        Path  path in
            path.move(to: .zero)
            path.addLine(to: CGPoint(x: width/2, y: offset))
            path.move(to: CGPoint(x: width/2, y: offset))
            path.addLine(to: CGPoint(x: width, y: 0))
        
    


struct ContentView: View 
    
    @State private var change = false
    
    private let arrowWidth: CGFloat = 80
    
    
    var body: some View 
        MyArrow(width: arrowWidth, offset: change ? -20 : 20)
        .stroke(style: StrokeStyle(lineWidth: 12, lineCap: .round))
        .frame(width: arrowWidth)
        .foregroundColor(.green)
        .animation(.default)
        .onTapGesture  change.toggle() 
        .padding(.top, 300)
    

【讨论】:

很酷的答案。 (已投票。)我几乎没有看过 SwiftUI。我知道如何使用 CAAnimation 和 CAShapeLayer 做到这一点,但不明白 this 方法的工作原理。你能用一些解释它是如何工作的来充实你的答案吗? @DuncanC,在状态改变时 SwiftUI 渲染引擎检测到修改后的 MyArrow 视图,并且因为它是可动画的,所以使用当前上下文动画的设置将 animatableData 从旧值插入到新值,即绘制它。 .animation(.default)。你可以找到好的详细文章swiftui-lab.com/category/animations。

以上是关于SwiftUI |动画此路径形状的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 swiftUI 沿自定义路径移动视图/形状?

SwiftUI 奇怪的动画行为与 systemImage

SwiftUI 视图以意想不到的路径动画

SwiftUI之深入解析高级动画的路径Paths

SwiftUI Tips 001:SwiftUI 概览

在 SwiftUI 中沿路径填充颜色渐变