这个技术项目起步比较容易,经过几番曲折,然后发展为更高级的动画,但是我希望它给你一个强大而灵活的想法!– SwiftUI的动画系统。

正如我之前所说,动画既要使你的应用看起来很棒,又要增加额外的含义。因此,除了让视图突然消失之外,你还可以添加一个过渡来帮助用户了解正在发生的变化吗?

另外,不要忘记在用户界面中看起来很有趣。我一直以来排名第一的最喜欢的iOS动画是Apple移至iOS 7时抛弃的动画,它是用于在电子钱包应用中删除通行证的动画–出现了金属粉碎机,将通行证切成十几条,然后掉了下来。它仅比当前动画花费了几分之一秒的时间,但它也很有趣。

挑战

返回到Guess the Flag项目并添加一些动画:

  • 当你点击正确的标志时,使其在Y轴上旋转360度。
  • 使其他两个按钮淡出至25%的不透明度。
  • 如果你点击了错误的标志?好吧,这取决于你–发挥创意!

代码

点击错误的标志后,正确的标志会有一个无限循环的缩放动画

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//
// ContentView.swift
// GuessTheFlag
//
// Created by 张洪Hoo on 2020/1/20.
// Copyright © 2020 张洪Hoo. All rights reserved.
//

import SwiftUI

struct ImgView: ViewModifier {
func body(content: Content) -> some View {
content
.clipShape(Capsule())
.overlay(Capsule().stroke(Color.black, lineWidth: 1))
.shadow(color: .black, radius: 2)
}
}

extension View {
func flagimg() -> some View {
self.modifier(ImgView())
}
}

struct ContentView: View {
@State private var showingScore = false
@State private var scoreTitle = ""
@State private var score = 0

@State private var countries = ["Estonia", "France", "Germany", "Ireland", "Italy", "Nigeria", "Poland", "Russia", "Spain", "UK", "US"].shuffled()
@State private var correctAnswer = Int.random(in: 0...2)

@State private var animationAmount:[Double] = [0,0,0]
@State private var animationOpacity:[Double] = [1,1,1]
@State private var animationSize:[CGFloat] = [1,1,1]

var body: some View {
ZStack {
LinearGradient(gradient: Gradient(colors: [.blue, .black]), startPoint: .top, endPoint: .bottom).edgesIgnoringSafeArea(.all)
VStack(spacing: 30.0) {
VStack {
Text("Tap the flag of")
.foregroundColor(Color.white)

Text(countries[correctAnswer])
.font(.largeTitle)
.fontWeight(.black)
.foregroundColor(Color.white)

Text("Score: \(score)")
.foregroundColor(Color.white)
.padding(.top)

}

ForEach(0 ..< 3) { number in

Button(action: {

self.flagTapped(number)
// self.askQuestion()
}) {
Image(self.countries[number])
.renderingMode(.original)
.flagimg()


}.rotation3DEffect(Angle(degrees: self.animationAmount[number]), axis: (x: 0, y: 1, z: 0))
.opacity(self.animationOpacity[number])
.animation(.default)
.scaleEffect(self.animationSize[number])
.animation( Animation.easeInOut(duration: 1)
.repeatForever(autoreverses: true))
}

Spacer()

}

}.alert(isPresented: $showingScore) {
Alert(---
title: Text(scoreTitle), message: Text("Your score is \(score)"), dismissButton: .default(Text("Continue")))
}
}
func flagTapped(_ number: Int) {
if number == correctAnswer{
self.animationAmount[self.correctAnswer] += 360.0
scoreTitle = "Correct"
self.score += 1

for num in 0 ..< 3 {
if num == self.correctAnswer {
self.animationOpacity[num] = 1
}else {
self.animationOpacity[num] = 0.25
}
}

}else {
scoreTitle = "Wrong![]That's \(countries[number]) flag"
self.score -= 1

self.animationSize[correctAnswer] = 1.2
for num in 0 ..< 3 {
if num == self.correctAnswer {
self.animationOpacity[num] = 1
}else {
self.animationOpacity[num] = 0.25
}
}
}



showingScore = true
}

func askQuestion(){

countries.shuffle()
correctAnswer = Int.random(in: 0...2)
animationOpacity = [1,1,1]
animationSize = [1,1,1]
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

参考资料

查看下一天的SwiftUI学习笔记

关于100days英文课程