0
votes

i have a Shake annimation extension like this, import SwiftUI

struct WRShake: GeometryEffect {
    var amount: CGFloat = 10
    var shakesPerUnit = 3
    var animatableData: CGFloat

    func effectValue(size: CGSize) -> ProjectionTransform {
        ProjectionTransform(CGAffineTransform(translationX: amount * sin(animatableData * .pi * CGFloat(shakesPerUnit)), y: 0))
    }
}

extension View {
    
    func wrshake(amount: CGFloat = 10, shakeUnits: Int = 4, animatableData: CGFloat) -> some View {
        return modifier(WRShake(amount: amount, shakesPerUnit: shakeUnits, animatableData: animatableData))
    }
}

then in the contentView, i got this

var body: some Scene {
        WindowGroup {
            NavigationView {
                VStack {
                    Text("111")
                        .padding()
                        .background(Color.blue)
                        .wrshake(animatableData: self.shakeValue)
//                        .animation(.easeInOut(duration: 0.5))
                        .layoutPriority(1)

                    Button {
                        withAnimation(.easeInOut(duration: 1)) {
                            self.shakeValue += 1
                        }
//                        self.shakeValue += 1
                    } label: {
                        Text("shake")
                    }
                }
            }
        }

then strange thing is,if i don't apply .animation(.easeInOut(duration: 0.5)) to then Text View, there is no animation.

anyone knows why?

thanks

2
my xcode version is : Version 12.5.1 (12E507)Chao Huang

2 Answers

0
votes
    WindowGroup {
            NavigationView {
//                StartUpView()
                ContentView()
            }
//            .navigationViewStyle(StackNavigationViewStyle())

    }

it turns out that, if i wrap everything into ContentView, it works, but why?

0
votes

I think because you are using explicit animations on the :App class and that class doesn't handle explicit animations. Explicit animations is when you use the withAnimation block and leave the system to figure out how the animate.

And i suppose in @main class you did put the @State var shakeValue: CGFloat = 0 but becasuse it's a :App and not a View it doesn't change.

it works adding the .animation(.easeInOut(duration: 0.5)) because it returns a new view that handle the animations like when your extracting the view like ContentView().

(implicit animations are when you apply the modifier .animation(...))