如何在SwiftUI中暂停动画? [英] How to pause an animation in SwiftUI?

查看:88
本文介绍了如何在SwiftUI中暂停动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道在启动后如何停止 withAnimation(_:)方法.

I don't know how to stop withAnimation(_:) method after starting it.

我正在用SwiftUI编写我的第一个应用程序,我想创建一个进度圈,该进度圈将由用户通过按钮进行控制-开始按钮,它将开始动画,其中圆圈将在末尾填充并且停止按钮将具有保存填充点的实际状态并停止动画.

I am writing my first app with SwiftUI and I want to create a progress circle, which will be controlled with buttons by user - start button, which will start animation, where circle will be unfilled at the end and stop button will have to save actual state of the fill point and stop the animation.

我的主视图:

struct MainView: View {
  @State private var fillPoint = 1.0 
  @State private var animationDuration = 10.0

  private var ring: Ring {
    let ring = Ring(fillPoint: self.fillPoint)
    return ring
  }

  var body: some View {
    VStack {
      ring.stroke(Color.red, lineWidth: 15.0)
        .frame(width: 200, height: 200)
        .padding(40)
      HStack {
        Button(action: {
          withAnimation(.easeIn(duration: self.animationDuration)) {
              self.fillPoint = 0
          }
        }) {
          Text("Start")
        }
        Button(action: {
          // what should I do here?
        }) {
          Text("Stop")
        }
      }
    }
  }
}

Ring的结构:

struct Ring: Shape {
  var startArcAngle: Double = 360.0

  var fillPoint: Double {
    willSet {
      startArcAngle = 360 * newValue
    }
  }

  internal var animatableData: Double {
    get { return fillPoint }
    set { fillPoint = newValue }
  }

  internal func path(in rect: CGRect) -> Path {
    let endArcAngle = 0.0

    var path = Path()

    path.addArc(center: CGPoint(x: rect.size.width / 2,
                                y: rect.size.height / 2),
                radius: rect.size.width / 2,
                startAngle: .degrees(startArcAngle - 90),
                endAngle: .degrees(endArcAngle - 90),
                clockwise: true)

    return path
  }
}

我尝试操纵 animatableData 值,但是在Ring的结构外部,它总是返回0.0(值是动画开始时在动画结束时要实现的值),并且在Ring的结构内部按我的意愿进行打印(0.96xxxx-> 0.94xxxx等),但是在Ring的结构之外进行打印总是返回1.0或0.0.

I've tried to manipulate animatableData value, but outside Ring's struct it's always returning 0.0 (value which is my code going to achieve at the end of animation if it's started) and inside Ring's struct it prints as I would like (0.96xxxx -> 0.94xxxx, etc.), but taking this outside of Ring's struct always returns 1.0 or 0.0.

推荐答案

似乎没有停止动画的控件.

It looks like there is no control to stop animation.

由于您的要求是在进度中间开始和停止抽奖,因此另一种解决方案是使用 Timer .棘手的一点是根据计时器的持续时间清除弧线.

As your requirement is to start and stop the draw in the middle of progress, one alternate solution is to use a Timer. The tricky point is to clear the arc based on the timer duration.

这是我在 MainView 中进行更改的代码:

Here is the code I made a change in your MainView:

注意:根据您的选择调整动画持续时间.

struct MainView: View {
    @State private var fillPoint = 1.0
    @State private var animationDuration = 10.0
    @State private var  stopAnimation = true
    @State private var countdownTimer: Timer?
    
    private var ring: Ring {
        let ring = Ring(fillPoint: self.fillPoint)
        return ring
    }
    
    var body: some View {
        VStack {
            ring.stroke(Color.red, lineWidth: 15.0)
                .frame(width: 200, height: 200)
                .padding(40)
                .animation(self.stopAnimation ? nil : .easeIn(duration: 0.1))
            HStack {
                Button(action: {
                    self.stopAnimation = false
                    self.countdownTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { _ in
                        guard self.animationDuration > 0 else {
                            self.countdownTimer?.invalidate()
                            return
                        }
                        self.fillPoint = self.animationDuration/10
                        self.animationDuration -= 0.1
                    })
                }) {
                    Text("Start")
                }
                Button(action: {
                    self.countdownTimer?.invalidate()
                    self.stopAnimation = true
                }) {
                    Text("Stop")
                }
            }
        }
    }
}

这篇关于如何在SwiftUI中暂停动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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