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

Day 34, conditional animation

Forums > 100 Days of SwiftUI

So the challenge is:

**Go back to the Guess the Flag project and add some animation:

When you tap the correct flag, make it spin around 360 degrees on the Y axis.

I know that I need to make a conditional animation... so I tried using a ternary operator.. the problem is.. I've never seen ternary operators work with methods that take more than one argument... for example I know that

.background(someBool ? .red : .blue) works.. but how about:

.rotation3DEffect(someBool ?. .degrees(someCFGValue), axis: x: 0, y: 0, z: 0 : .degrees.............. a so after some tweaking I got the ternary operator to work, but it rotates all 3 buttons.. not just the correct one. So what do you guys suggest? Here is a snapshot of what I have now (Cant upload a photo like i thought)

3      

Instead of posting an image, post your code between backticks ```, so it shows up like this:

struct ContentView: View {
    var body: some View {
        Text("Hello world!")
    }
}

4      


 @State private var animationState = false

 //........

ForEach(0 ..< 3) { number in
                               Button(action: {

                                withAnimation{self.flagTapped(number)
                                    animationAmount += 360.0
                                }
                               }) {
                                   Image(self.countries[number])
                                    .renderingMode(.original)
                                    .clipShape(Capsule())
                                    .overlay(Capsule().stroke(Color.black, lineWidth: 1))
                                    .shadow(color: .black, radius: 2)

                               }.rotation3DEffect(animationState ? .degrees(animationAmount) : .degrees(animationAmount), axis: (x: 0, y: 1, z: 0))

                               //Thats the ternary operator ^^

     //....

  func flagTapped(_ number: Int) {
        if number == correctAnswer {
            scoreTitle = "Correct"
            score += 5
            detailedMessage = "That is \(countries[number])"
            animationState = true

        } else {
            scoreTitle = "Wrong"
            score -= 5
            detailedMessage = "Wrong, that is \(countries[number])"
        }

        showingScore = true
    }

    // Func for correct button tap that sets the condition for animation

3      

I've been banging my head against this one for a while, and I manage to get the individual buttons to rotate individually, but couldn't get the opacity to work with it... yet.

It took a while, but it dawned on me that we are basically attaching the animation to the ForEach view. So naturally I split up the buttons into 3 separate ones. But it didn't work.

I then realized we are using the same variable to update the animation. animationAmount changes, and they all have their rotation updated.

So I did the sensible thing and created 3 different variables to be used for each separate button like so:

    @State private var animateAmountOne = 0.0
    @State private var animateAmountTwo = 0.0
    @State private var animateAmountThree = 0.0

and for the buttons here's the change necessary:

                //ButtonOne
                Button(action: {
                    withAnimation(.interpolatingSpring(stiffness: 2, damping: 1)) {
                        self.flagTapped(0)
                        if self.animateCorrect {
                            self.animateAmountOne += 360
                        }
                    }
                }) {
                    FlagView(flagImage: self.countries[0])
                }
                .rotation3DEffect(.degrees(animateAmountOne), axis: (x: 0, y: 1, z: 0))

1- notice that I hard-coded the buttons numbers. we know the range we use in the ForEach are the numbers: 0, 1, 2. So make sure to update accordingly for each button. self.flagTapped(0), self.flagTapped(1), self.flagTapped(2) and do the same for the image. I created a struct for the image to reduce clutter in the button.

2- notice how we end up using a specifc amount that relates to this button only. Which only ever gets updated at the right time.

3- The animation certainly needs work. It's rough and continues after the game updates. I know.

Now the challenge of figuring out the opacity change. and then the wrong guess scenario.

3      

@MarcusKay

You didn't need to make three separate animationAmounts, you could have added a ternary expression in the degrees parameter:

     ForEach(0 ..< 3) { number in

        Button(action: {
            // flag was tapped

            withAnimation(.interpolatingSpring(stiffness: 5, damping: 1)) {
                if  self.flagTapped(number) {
                    self.animationAmount += 360
                 }
              }
         }) {
             CapsuleFlag(imageName: self.countries[number])
         }    
          .rotation3DEffect(.degrees( (number == correctAnswer) ? animationAmount : 0.0), axis: (x: 0, y: 0, z: 1))
      }

I changed the axis of rotation for my own benefit, I like it better lol.

3      

@Jargen89

Excuse me while I go slap my face........

I went entirely and totally blind to the fact that we had correctAnswer. Just blank. Was thinking of the ternary operator, but couldn't think of what to use it with.... Oh well... Thanks.

This is gonna crack me up for a while. It's always the smallest things.

And yea, I'll fool around with the animation.... and some of the other approaches I've been reading...

3      

This is gonna crack me up for a while. It's always the smallest things.

@MarcusKay It happens to the best of us, no worries.

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 April 28th.

Click to save your free spot now

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.