Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to STOP Animation().repeatForever in SwiftUI

In SwiftUI I am trying to start and STOP an animation with a button. I can't find a method within SwiftUI that lets me stop an automation. In Swift 4 I used to say "startButton.layer.removeAllAnimations()". Is there an equivalent in SwiftUI?

For the code below, how would I used the value of start to enable/disable the animation. I tried .animation(start ? Animation(...) : .none) without any luck [creates some odd animation within the button].

import SwiftUI

struct Repeating_WithDelay: View {
    @State private var start = false

    var body: some View {
        VStack(spacing: 20) {
            TitleText("Repeating")
            SubtitleText("Repeat With Delay")
            BannerText("You can add a delay between each repeat of the animation. You want to add the delay modifier BEFORE the repeat modifier.", backColor: .green)

            Spacer()

            Button("Start", action: { self.start.toggle() })
                .font(.largeTitle)
                .padding()
                .foregroundColor(.white)
                .background(RoundedRectangle(cornerRadius: 10).fill(Color.green))
                .overlay(
                    RoundedRectangle(cornerRadius: 10)
                        .stroke(Color.green, lineWidth: 4)
                        .scaleEffect(start ? 2 : 0.9)
                        .opacity(start ? 0 : 1))
                .animation(Animation.easeOut(duration: 0.6)
                    .delay(1) // Add 1 second between animations
                    .repeatForever(autoreverses: false))

            Spacer()

        }
        .font(.title)
    }
}

struct Repeating_WithDelay_Previews: PreviewProvider {
    static var previews: some View {
        Repeating_WithDelay()
    }
}
like image 915
Dan Schümacher Avatar asked Jan 20 '20 17:01

Dan Schümacher


People also ask

How do I slow down an animation in SwiftUI?

When you create any animation – implicitly, explicitly, or with bindings – you can attach modifiers to that animation to adjust the way it works. For example, if you want an animation to start after a certain number of seconds you should use the delay() modifier.

How do I animate a view in SwiftUI?

If you want a SwiftUI view to start animating as soon as it appears, you should use the onAppear() modifier to attach an animation.

How do I repeat an animation in SwiftUI?

To make our animation repeat, we use . repeatForever() . The default behavior of repeat forever is autoreverse, that's mean our animation will scale from 1 to 0.5 then 0.5 back to 1, creating a seamless loop of animation.

What is the default animation SwiftUI?

default is a basic animation with 0.35 seconds duration and an ease-in-ease-out timing curve.


1 Answers

Update - retested with Xcode 13.4 / iOS 15.5

enter image description here

The following should work, moved animation into overlay-only and added conditional to .default (tested with Xcode 11.2 / iOS 13.2)

Button("Start", action: { self.start.toggle() })
    .font(.largeTitle)
    .padding()
    .foregroundColor(.white)
    .background(RoundedRectangle(cornerRadius: 10).fill(Color.green))
    .overlay(
        RoundedRectangle(cornerRadius: 10)
            .stroke(Color.green, lineWidth: 4)
            .scaleEffect(start ? 2 : 0.9)
            .opacity(start ? 0 : 1)
            .animation(start ? Animation.easeOut(duration: 0.6)
                .delay(1) // Add 1 second between animations
                .repeatForever(autoreverses: false) : .default, value: start)
    )

On GitHub

like image 191
Asperi Avatar answered Oct 24 '22 15:10

Asperi