UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Day 33: Animating Gestures

Forums > 100 Days of SwiftUI

Hello,

I came across this issue while following the tutorial for Animating Gestures from day 33. The code tries to animate a drag gesture, wherein the individual letters from the text are attached with an increasing delay.

The animation works fine only for the first drag motion. After that, the animation stops working completely until I let go (where the letters go back to their original position and the color change is animated).

I am using using Xcode 15.0 and iOS 17.0

However, upon setting the minimum deployment parameter to iOS 15.0 in the target settings, the animation works as expected and as shown in the tutorial.

Has anyone noticed this behaviour and has an explanation for it? Thanks in advance!

Code from the tutorial

struct ContentView: View {
    let letters = Array("Hello, SwiftUI")
    @State private var enabled = false
    @State private var dragAmount = CGSize.zero

    var body: some View {
        HStack(spacing: 0) {
            ForEach(0..<letters.count, id: \.self) { num in
                Text(String(letters[num]))
                    .padding(5)
                    .font(.title)
                    .background(enabled ? .blue : .red)
                    .offset(dragAmount)
                    .animation(
                        .default.delay(Double(num) / 20), 
                        value: dragAmount
                    )
            }
        }
        .gesture(
            DragGesture()
                .onChanged { dragAmount = $0.translation }
                .onEnded { _ in
                    dragAmount = .zero
                    enabled.toggle()
                }
        )
    }
}

3      

@Adnan asks:

Has anyone noticed this behaviour and has an explanation for it?

Confirmed!

Yes! I copied your code above to a new project and, indeed, the animation does not work as advertised unless the minimum deployment is set to iOS 15.

Cause

I have no idea why the delay on the default animation isn't well, delaying after you move, then stop.

Clearly the dragAmount is changing because the entire term ("Hello, Swift") is moving around the screen. But for some reason the delay stops working.

Default and Spring Animation

The new default animation is the .spring animation. If you change the animation to .linear, or .easeIn, the animation works as advertised. I think the .spring animation (default in iOS17) is the culprit. Perhaps it doesn't have time to recover from its springiness so the delay stops working? This also explains why setting the target to iOS 15 works, because the .default there is NOT .spring. Someone might propose a better explanation.

This is Weird!

I also tried this on my iPhone running iOS 17 and can confirm the delay stopped working after moving the text up or down. I'd say if you can get other confirmation about the .spring and .bouncy animations you may want to log this as a bug. Nice find!

3      

@Obelix

Thanks for the solve!

3      

Hello,

I came across this issue while following the tutorial for Animating Gestures from day 33. The code tries to animate a drag gesture, wherein the individual letters from the text are attached with an increasing delay.

The animation works fine only for the first drag motion. After that, the animation stops working completely until I let go (where the letters go back to their original position and the color change is animated).

I am using using Xcode 15.0 and iOS 17.0

However, upon setting the minimum deployment parameter to iOS 15.0 in the target settings, the animation works as expected and as shown in the tutorial.

Has anyone noticed this behaviour and has an explanation for it? Thanks in advance!

Code from the tutorial

struct ContentView: View { let letters = Array("Hello, SwiftUI") @State private var enabled = false @State private var dragAmount = CGSize.zero

var body: some View {
    HStack(spacing: 0) {
        ForEach(0..<letters.count, id: \.self) { num in
            Text(String(letters[num]))
                .padding(5)
                .font(.title)
                .background(enabled ? .blue : .red)
                .offset(dragAmount)
                .animation(
                    .default.delay(Double(num) / 20), 
                    value: dragAmount
                )
        }
    }
    .gesture(
        DragGesture()
            .onChanged { dragAmount = $0.translation }
            .onEnded { _ in
                dragAmount = .zero
                enabled.toggle()
            }
    )
}

}

3      

Hacking with Swift is sponsored by Superwall

SPONSORED Superwall lets you build & test paywalls without shipping updates. Run experiments, offer sales, segment users, update locked features and more at the click of button. Best part? It's FREE for up to 250 conversions / mo and the Superwall team builds out 100% custom paywalls – free of charge.

Learn More

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.