[英]SwiftUI - Animate a view on button press
我剛剛完成了#hackingwithswift 的第 6 課。 我正在為一個根本不應該那么難的挑戰而生氣......
在這里,我有一個名為 GuessTheFlag 的工作游戲,其中用戶必須選擇指示的正確標志,然后在傳遞到下一輪之前收到警報。
我的問題很簡單:我想讓不正確的標志視圖變得不透明,並且在選擇答案時讓正確的標志視圖旋轉 360 度。 這應該全部發生在警報之后,直到用戶單擊“繼續”。
可選:我還想完全刪除警報,並在旋轉動畫完成后讓游戲進入下一輪。 我可以將圓形更改綁定到動畫的結尾嗎? 還是我必須使用某種 sleep() 命令?
import SwiftUI
struct FlagView: View {
var flag: String
var body: some View {
Image(flag)
.renderingMode(.original)
.clipShape(Capsule())
.overlay(Capsule().stroke(Color.black, lineWidth: 2))
.shadow(color: .black, radius: 2)
}
}
struct ContentView: View {
@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 showingScore = false
@State private var scoreTitle = ""
@State private var score = 0
@State private var animate = false
var alert: Alert {
if scoreTitle == "Wrong" {
return Alert(title: Text(scoreTitle), message: Text("The correct answer was \(countries[correctAnswer])"), dismissButton: .default(Text("Restart")) {
self.askQuestion()
animate = false
})
}
else {
return Alert(title: Text(scoreTitle), message: Text("Your Score is \(score)"), dismissButton: .default(Text("Continue")) {
self.askQuestion()
animate = false
})
}
}
var body: some View {
ZStack{
LinearGradient(gradient: Gradient(colors: [.black,.blue, .orange]), startPoint: .top, endPoint: .bottom).edgesIgnoringSafeArea(.all)
VStack(spacing: 40) {
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 {
self.flagTapped(number)
animate.toggle()
}
}) {
FlagView(flag: self.countries[number])
}
}
Text("Your Score is \(score)")
.font(.headline)
.fontWeight(.black)
.foregroundColor(Color.white)
Spacer()
}
}
.alert(isPresented: $showingScore) {
alert
}
}
func flagTapped(_ number: Int) {
if number == correctAnswer {
scoreTitle = "Correct"
score += 1
} else {
scoreTitle = "Wrong"
score = 0
}
showingScore = true
}
func askQuestion() {
countries.shuffle()
correctAnswer = Int.random(in: 0...2)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
任何幫助,將不勝感激! 提前致謝
只需在FlagView
上應用視圖修飾符opacity
和rotationEffect
而不是使用離散值(例如.opacity(0.1)
)使其成為有條件的:
.opacity((self.animate && number != correctAnswer) ? 0.1 : 1.0)
動畫部分將通過 SwiftUI 自動完成。 請參閱下面的我的工作示例:
import SwiftUI
struct FlagView: View {
var flag: String
var body: some View {
Text(flag)
}
}
struct ContentView: View {
@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 showingScore = false
@State private var scoreTitle = ""
@State private var score = 0
@State private var animate = false
var alert: Alert {
if scoreTitle == "Wrong" {
return Alert(title: Text(scoreTitle), message: Text("The correct answer was \(countries[correctAnswer])"), dismissButton: .default(Text("Restart")) {
self.askQuestion()
})
}
else {
return Alert(title: Text(scoreTitle), message: Text("Your Score is \(score)"), dismissButton: .default(Text("Continue")) {
self.askQuestion()
})
}
}
var body: some View {
ZStack{
LinearGradient(gradient: Gradient(colors: [.black,.blue, .orange]), startPoint: .top, endPoint: .bottom).edgesIgnoringSafeArea(.all)
VStack(spacing: 40) {
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(.easeInOut(duration: 0.5)) {
self.animate = true
}
self.flagTapped(number)
}) {
FlagView(flag: self.countries[number])
.opacity((self.animate && number != correctAnswer) ? 0.1 : 1.0)
.rotationEffect(.init(degrees: (self.animate && number == correctAnswer) ? 360.0 : 0.0))
}
}
Text("Your Score is \(score)")
.font(.headline)
.fontWeight(.black)
.foregroundColor(Color.white)
Spacer()
}
}
.alert(isPresented: $showingScore) {
alert
}
}
func flagTapped(_ number: Int) {
if number == correctAnswer {
scoreTitle = "Correct"
score += 1
} else {
scoreTitle = "Wrong"
score = 0
}
showingScore = true
}
func askQuestion() {
self.animate = false
countries.shuffle()
correctAnswer = Int.random(in: 0...2)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
為了您的選購問題(如例如,你可以引入一個自定義的修改在這里)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.