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

Project 6 Flag animation please help!

Forums > 100 Days of SwiftUI

hello all

im going mad woth this one.

i can seem to make the flag that is tapped spin.

ive tried so many different things.

i got to the point ehere i could make The correct flag spin but not the flag that was tapped.

This latest version of the code was an attempt to correct that but which flag spins seems to be different every time and I can't work out why.

this latest version of the code was an attempt to correct that but which flag spins seems to be different every time and I can't work out why Please help!

edit: im using swift playgrounds 4 on the iPad. This means I've had to make slight changes to the way I reference images as you can see.

import SwiftUI

struct FlagImage: View { // i was using this originally but in an effort to get this working ive abandoned it!
    @State private var flagTapped = false
    var image: String

    var body: some View {
        Image(image)
            .renderingMode(.original)
            .clipShape(RoundedRectangle(cornerRadius: 20))
            .shadow(radius: 5)
            .rotationEffect(.degrees(flagTapped ? 360 : 0))
            .animation(.default, value: flagTapped)
            .onTapGesture {
                flagTapped.toggle()
            }
    }

}

struct ContentView: View {
    @State private var highScore = 0
    @State private var correctFlag = ""
    @State private var rounds = 0
    @State private var hasEnded = false
    @State private var wasCorrect = true
    @State private var messageText = ""
    @State private var userScore = 0
    @State private var showingScore = false
    @State private var scoreTitle = ""
    @State private var countries = ["Estonia@2x", "France@2x","Germany@2x","Ireland@2x","Italy@2x","Nigeria@2x","Poland@2x","Russia@2x","Spain@2x","UK@2x","US@2x"].shuffled()
    @State private var correctAnswer = Int.random(in: 0...2)
    @State private var animationAmount = 0.0
    @State private var flagTapNumber = 1

    var body: some View {
        ZStack {
            RadialGradient(stops: [
                .init(color: Color(red: 0.1, green: 0.2, blue: 0.45), location: 0.3),
                .init(color: Color(red: 0.76, green: 0.15, blue: 0.26), location: 0.3),
            ], center: .top, startRadius: 200, endRadius: 700)
            .ignoresSafeArea()
            .ignoresSafeArea()
            VStack {
                Spacer()
                Text("Guess the flag")
                    .font(.largeTitle.bold())
                    .foregroundColor(.white)
                VStack(spacing: 15){
                    VStack{
                        Text("Tap the flag of")
                            .foregroundStyle(.secondary)
                            .font(.subheadline.weight(.heavy))
                        Text(countries[correctAnswer].dropLast(3))
                        .font(.largeTitle.weight(.semibold))
                    }
                    ForEach(0..<3) { number in
                        Button{
                        //flag was tapped
                            withAnimation {
                                animationAmount += 360.0
                            }
                            flagTapNumber = number
                            print("the number is \(number)")
                            print("the flagTapNumer is\(flagTapNumber)")
                            flagTapped(number)
                        } label: {
                            //FlagImage(image: countries[number])
                            Image(countries[number])
                                .renderingMode(.original)
                                .clipShape(RoundedRectangle(cornerRadius: 20))
                                .shadow(radius: 5)
                        }.rotation3DEffect(.degrees(number == flagTapNumber ? animationAmount: 0.0), axis: (x: 0, y: 1, z: 0))
                    }
                }
                .frame(maxWidth: .infinity)
                .padding(.vertical, 20)
                .background(.regularMaterial)
                .clipShape(RoundedRectangle(cornerRadius: 20))

                Spacer()
                Spacer()
                HStack {
                    Text("Score \(userScore)")
                        .foregroundColor(.white)
                        .font(.title.bold())
                    Spacer()
                    VStack{
                        Text("High Score \(highScore)")
                            .foregroundColor(.white)
                            .font(.title.bold())
                        Button("Reset") {
                            highScore = 0
                        }
                    }
                }
                Spacer()
            }
            .padding()
        } 
        .alert(scoreTitle, isPresented: $showingScore) {
            Button("Continue", action: askQuestion)
        } message: {
            if wasCorrect == true {
                Text("Your new score is \(userScore)")
            } else {
                Text(messageText)
            }
        }
        .alert("Game Over", isPresented: $hasEnded) {
            Button("Restart game", action: gameOver)
        } message: {
            if wasCorrect == true {
                Text("Correct! Your final score was \(userScore)")
            } else {
                Text("Wrong! That was the flag for \(correctFlag). Your final score was \(userScore)")
            }
        }
    }
    func flagTapped(_ number: Int) {
        rounds += 1
        correctFlag = String(countries[number].dropLast(3))
        guard rounds < 8 else {
            if number == correctAnswer {
                userScore += 1
                wasCorrect = true
            }
            hasEnded = true
            return
        }
        let wrongText = "Wrong! That was the flag for \(countries[number].dropLast(3))!"
        if number == correctAnswer{
            scoreTitle = "Correct!"
            userScore += 1
            wasCorrect = true
        } else {
            scoreTitle = "Wrong!"
            wasCorrect = false
            messageText = wrongText
        }
        showingScore = true
    }

    func askQuestion() {
        countries.shuffle()
        correctAnswer = Int.random(in: 0...2)
    }

    func gameOver() {
        askQuestion()
        if userScore > highScore {
            highScore = userScore
        }
        userScore = 0
        rounds = 0

    }
}

2      

ok so i finally did it.

BUT

i had to start again with a simple three button app to simplify my code. i also had to creat a custom button so that each view had its own state variable. and it works and looks nice

thoughts please - was there a better or easier way?

import SwiftUI

struct customButton: View {
    var text: String

    @State private var clicked = false

    var body: some View {
        Button {
            withAnimation {
                clicked.toggle()
            }
        } label: {
            Rectangle()
                .frame(width: 100, height: 100)
                .background(.blue)
                .clipShape(RoundedRectangle(cornerRadius: 20))
                .imageScale(.large)
                .overlay() {
                    Text("No \(text)")
                        .foregroundColor(.white)
                }
                .foregroundColor(.accentColor)
                .rotation3DEffect(.degrees(clicked ? 360 : 0), axis: (x: 0, y: 1, z: 0))
        }
    }

}

struct ContentView: View {
    @State private var buttons = [0,1,2]
    var body: some View {
        VStack {

            ForEach(buttons, id: \.self) { button in 
                customButton(text: String(button))
            }

        }

    }
}

3      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

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.