Day 32, 33, 34 of #100DaysOfSwiftUI (again)

For getting better understanding, I decided to go through again.

Start 100DaysOfSwiftUI from 2020.Mar.18th.

Day X: Project 6, part one, two, three
done with X hours

New findings: followings are new findings

implicit animation
SwiftUI knows well about View's state and he can interpolate the differences with animation, this is implicit animation.
binding animation
SwiftUI knows "from view" and "to view" which binding variable will create, so he can make the animation between those.

finally I understand how to control animation (partially) !
here is the code with implementing challenge.

struct ContentView: View {
    @State var countries = ["Estonia", "France", "Germany", "Ireland", "Italy",
                     "Nigeria", "Poland", "Russia", "Spain", "UK", "US"].shuffled()
    @State var correctAnswer = Int.random(in: 0...2)
    
    @State private var showingScore = false
    @State private var scoreTitle = ""
    @State private var userScore = 0
    @State private var rotateAngle = [0.0, 0.0, 0.0]
    @State private var opacity = [1.0, 1.0, 1.0]
    
    var body: some View {
        ZStack {
            LinearGradient(gradient: Gradient(colors: [.blue, .black]), startPoint: .top, endPoint: .bottom)
            .edgesIgnoringSafeArea(.all)
            VStack(spacing:30) {
                VStack {
                    Text("Tap the flag of")
                        .foregroundColor(.white)
                    Text(countries[correctAnswer])
                        .font(.largeTitle)
                        .fontWeight(.black)
                        .foregroundColor(.white)
                }
                ForEach(0 ..< 3) { number in
                    Button(action: {
                        withAnimation(
                            Animation.easeInOut(duration: 2)
                            ) {
                                if self.flagTapped(number) == true {
                                    self.rotateAngle[number] = 360
                                    self.changeOpacityOfOtherFlag(num: number)
                                }
                            self.showingScore = true
                        }
                    }) {
                        FlagImage(flagName: self.countries[number])
                    }
                    .rotation3DEffect(.init(degrees: self.rotateAngle[number]), axis: (x:0, y:1, z:0))
                    .opacity(self.opacity[number])
                }
                Text("Current score : \(userScore)").foregroundColor(.white)
                Spacer()
            }
        }
        .alert(isPresented: $showingScore) {
            Alert(title: Text(scoreTitle),
                  message: Text("Your score is \(userScore)"),
                  dismissButton: .default(Text("Continue")) {
                    self.askQuestion()
            })
        }
    }
    
    func flagTapped(_ number:Int) -> Bool{
        if number == correctAnswer {
            scoreTitle = "Correct"
            userScore += 3
            return true
        } else {
            scoreTitle = "Wrong! \nThat is the flag of \(countries[number])."
            userScore -= 1
            return false
        }
    }
    
    func changeOpacityOfOtherFlag(num: Int) {
        self.opacity[0] = num == 0 ? 1 : 0.25
        self.opacity[1] = num == 1 ? 1 : 0.25
        self.opacity[2] = num == 2 ? 1 : 0.25
    }
    
    func askQuestion() {
        countries.shuffle()
        correctAnswer = Int.random(in: 0...2)
        self.rotateAngle = [0.0, 0.0, 0.0]
        self.opacity = [1.0, 1.0, 1.0]
    }
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です