Swiftui在使用路径绘制折线图的同时为每条线设置动画

时间:2020-07-04 06:36:22

标签: swiftui

我正在尝试使用SwiftUI,路径和形状为线形图制作动画。我无法让每个path.addLine在添加每行时都单独显示

这是我尝试过的



import SwiftUI

struct LineChartShape: Shape{
    
    var chartItems: [ChartItem]

    var animatableData: [ChartItem] {
        get { chartItems }
        set {
            self.chartItems = newValue
        }
    }

    
    func path(in rect: CGRect) -> Path {
        var path = Path()
        let width = rect.width
        let height = rect.height
        path.move(to: CGPoint(x: width * 0.05, y: height * 0.5))
        
        chartItems.forEach { chartItem in
            path.addLine(to: CGPoint(x: width * CGFloat(chartItem.x), y:  height * CGFloat(chartItem.y)))
        }
        
        return path
    }
    
    
}

struct LineChartShape_Previews: PreviewProvider {
    static var previews: some View {
        GeometryReader { geometry in
            
            LineChartShape(chartItems: [
                ChartItem(y: 0.5, x: 0.05),
                ChartItem(y: 0.4, x: 0.1),
                ChartItem(y: 0.2, x: 0.15),
                ChartItem(y: 0.3, x: 0.2),
                ChartItem(y: 0.3, x: 0.25),
                ChartItem(y: 0.4, x: 0.3),
                ChartItem(y: 0.5, x: 0.35),
                ChartItem(y: 0.3, x: 0.4),
                ChartItem(y: 0.6, x: 0.45),
                ChartItem(y: 0.65, x: 0.5),
                ChartItem(y: 0.5, x: 0.55),
                ChartItem(y: 0.5, x: 0.6),
                ChartItem(y: 0.4, x: 0.65),
                ChartItem(y: 0.45, x: 0.7),
                ChartItem(y: 0.3, x: 0.75),
                ChartItem(y: 0.3, x: 0.8),
                ChartItem(y: 0.2, x: 0.85),
                ChartItem(y: 0.3, x: 0.9)
            ])
                .stroke(Color.blue, lineWidth: 5)
                .animation(.easeInOut(duration: 10))
                

        }
    }
}

struct ChartItem: Identifiable{
    let id = UUID()
    var y: Float
    var x: Float
    
}

我是Swift的新手,所以我确定我缺少明显的东西,但我无法弄清楚。谢谢您的帮助

2 个答案:

答案 0 :(得分:3)

这里是可能解决方案的演示。经过Xcode 12测试。

demo

struct TestAnimateAddShape: View {
    @State private var end = CGFloat.zero
    var body: some View {
        GeometryReader { geometry in

            LineChartShape(chartItems: [
                ChartItem(y: 0.5, x: 0.05),
                ChartItem(y: 0.4, x: 0.1),
                ChartItem(y: 0.2, x: 0.15),
                ChartItem(y: 0.3, x: 0.2),
                ChartItem(y: 0.3, x: 0.25),
                ChartItem(y: 0.4, x: 0.3),
                ChartItem(y: 0.5, x: 0.35),
                ChartItem(y: 0.3, x: 0.4),
                ChartItem(y: 0.6, x: 0.45),
                ChartItem(y: 0.65, x: 0.5),
                ChartItem(y: 0.5, x: 0.55),
                ChartItem(y: 0.5, x: 0.6),
                ChartItem(y: 0.4, x: 0.65),
                ChartItem(y: 0.45, x: 0.7),
                ChartItem(y: 0.3, x: 0.75),
                ChartItem(y: 0.3, x: 0.8),
                ChartItem(y: 0.2, x: 0.85),
                ChartItem(y: 0.3, x: 0.9)
            ])
                .trim(from: 0, to: end)            // << here !!
                .stroke(Color.blue, lineWidth: 5)
                .animation(.easeInOut(duration: 10))
        }.onAppear { self.end = 1 }                  // << activate !!
    }
}

答案 1 :(得分:0)

很好的解决方案!然而,我建议删除动画修饰符并使用 WithAnimation 函数代替:

   withAnimation(.easeIn(duration: x) {
     self.end = 1 
   }

原因是如果你改变屏幕方向,我发现线条在屏幕上移动很奇怪......如果你只从 onAppear 开始动画,这是可以防止的。