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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
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] } } |
Sponsor Link