LAST CHANCE: Save 50% on all my Swift books and bundles! >>

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 Essential Developer.

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until July 28th.

Click to save your free spot now

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.