|
How do I add a "cancel" option to my "Restart" button?
Hi all, tackling Challenge 3 of Project 2.
Right now I have this:
import SwiftUI
struct ContentView: View {
@State private var showingScore = false //whether the alert is showing
@State private var scoreTitle = "" //title to be shown in the alert
@State private var userScore = 0 //the user's score playing the game
@State private var gameFinished = false //whether the game is finished at 8 questions
@State private var totalPlayed = 0 //tracking the number of questions answered
@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) //decide which country flag should be tapped.
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: 400).ignoresSafeArea()
VStack {
Spacer()
Text("Guess The Flag").font(.largeTitle.weight(.bold))
.foregroundColor(.white)
VStack(spacing: 15) {
VStack {
Text("Tap the flag of").foregroundStyle(.secondary).font(.subheadline.weight(.heavy))
Text(countries[correctAnswer]).font(.largeTitle.weight(.semibold))
}
ForEach(0..<3) {number in
Button {
flagTapped(number)
} label: {
Image(countries[number]).renderingMode(.original).clipShape(Capsule()).shadow(radius: 5)}
}.alert(scoreTitle, isPresented: $showingScore) {
Button("Continue", action: askQuestion)
} message: {
Text("Your socre is \(userScore)")
}
Button("Restart") {
gameFinished = true
}
.alert("Restarting", isPresented: $gameFinished) {
Button("Restart", role: .cancel, action: reset)
} message: {
Text("Your final score is \(userScore)")
}
}
.frame(maxWidth: .infinity)
.padding(.vertical, 20)
.background(.regularMaterial)
.clipShape(RoundedRectangle(cornerRadius: 20))
Spacer()
Spacer()
Text("Score: \(userScore)")
.foregroundColor(.white)
.font(.title.bold())
Text("Total Guessed: \(totalPlayed)")
.foregroundColor(.white)
.font(.title.bold())
Spacer()
}
.padding()
}
}
func flagTapped(_ number: Int) {
if totalPlayed == (8-1) {
gameFinished = true
}
else {
if number == correctAnswer {
scoreTitle = "Correct"
userScore += 1
} else {
scoreTitle = "Wrong! That is the flag of \(countries[number])"
}
}
totalPlayed += 1
showingScore = true
}
//resets the game by shuffling up the countries and picking a new correct answer
func askQuestion() {
countries.shuffle()
correctAnswer = Int.random(in: 0...2)
}
func reset() {
scoreTitle = "You have finished all 8 guesses"
userScore = 0
totalPlayed = 0
countries.shuffle()
}
}
How do I add a "cancel" click to my "Restart" button?
Besides that, anything I can improve here? Thanks a lot.
Thank you very much.
|
|
First get rid of the role: .cancel on your restart button. Then add a cancel button below it.
.alert("Restarting", isPresented: $gameFinished) {
Button("Restart", action: reset)
Button("Cancel", role: .cancel) {}
} message: {
Text("Your final score is \(userScore)")
}
You also might want to consider moving your alerts to the outer ZStack to group them together.
|
|
@vtabmow, thanks a lot for your comment. The cancel button worked.
I tried to put both alerts on the ZStack before, but only 1 worked. It seems that one of the alerts will be override if I put them both on the ZStack ?
|
|
Did you try this?
import SwiftUI
struct ContentView: View {
@State private var showingScore = false //whether the alert is showing
@State private var scoreTitle = "" //title to be shown in the alert
@State private var userScore = 0 //the user's score playing the game
@State private var gameFinished = false //whether the game is finished at 8 questions
@State private var totalPlayed = 0 //tracking the number of questions answered
@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) //decide which country flag should be tapped.
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: 400).ignoresSafeArea()
VStack {
Spacer()
Text("Guess The Flag").font(.largeTitle.weight(.bold))
.foregroundColor(.white)
VStack(spacing: 15) {
VStack {
Text("Tap the flag of").foregroundStyle(.secondary).font(.subheadline.weight(.heavy))
Text(countries[correctAnswer]).font(.largeTitle.weight(.semibold))
}
ForEach(0..<3) {number in
Button {
flagTapped(number)
} label: {
Image(countries[number]).renderingMode(.original).clipShape(Capsule()).shadow(radius: 5)}
}
Button("Restart") {
gameFinished = true
}
}
.frame(maxWidth: .infinity)
.padding(.vertical, 20)
.background(.regularMaterial)
.clipShape(RoundedRectangle(cornerRadius: 20))
Spacer()
Spacer()
Text("Score: \(userScore)")
.foregroundColor(.white)
.font(.title.bold())
Text("Total Guessed: \(totalPlayed)")
.foregroundColor(.white)
.font(.title.bold())
Spacer()
}
.padding()
}
.alert(scoreTitle, isPresented: $showingScore) {
Button("Continue", action: askQuestion)
} message: {
Text("Your socre is \(userScore)")
}
.alert("Restarting", isPresented: $gameFinished) {
Button("Restart", action: reset)
Button("Cancel", role: .cancel) {}
} message: {
Text("Your final score is \(userScore)")
}
}
func flagTapped(_ number: Int) {
if totalPlayed == (8-1) {
gameFinished = true
}
else {
if number == correctAnswer {
scoreTitle = "Correct"
userScore += 1
} else {
scoreTitle = "Wrong! That is the flag of \(countries[number])"
}
}
totalPlayed += 1
showingScore = true
}
//resets the game by shuffling up the countries and picking a new correct answer
func askQuestion() {
countries.shuffle()
correctAnswer = Int.random(in: 0...2)
}
func reset() {
scoreTitle = "You have finished all 8 guesses"
userScore = 0
totalPlayed = 0
countries.shuffle()
}
}
|
|
I don't remember if I've tried this, but it helps ! Thank you.
|
|
What do you think about my solution?
import SwiftUI
struct ContentView: View {
@State private var showingScore = false
@State private var showFinalScore = false
@State private var scoreTitle = ""
@State private var scoreTitleFinished = ""
@State private var score = 0
@State private var countries = [ "Estonia", "France", "Germany", "Ireland", "Italy", "Nigeria", "Poland", "Russia", "Spain", "UK", "US", "Monaco" ].shuffled()
@State private var correctAnswer = Int.random(in: 0...2)
@State private var selectedFlag = ""
@State private var numberOfQ = 0
var body: some View {
ZStack{
// radial gradient
RadialGradient(stops: [
.init(color: Color(red: 0.1, green: 0.8, blue: 0.95), location: 0.3),
.init(color: Color(red: 0.06, green: 0.9, blue: 0.6), location: 0.3)
], center: .top, startRadius: 200, endRadius: 700)
.ignoresSafeArea()
VStack{
Spacer()
Text("Guess the flag?")
.font(.largeTitle.weight(.bold))
.foregroundColor(.yellow.opacity(0.9))
VStack(spacing: 15){
VStack{
Text("Tap the flag off")
.foregroundStyle(.secondary)
.font(.subheadline.weight(.heavy))
Text(countries[correctAnswer])
.font(.largeTitle.weight(.semibold))
}
ForEach(0..<3){ number in
Button {
// flag was tapped
flagTapped(number)
} label: {
Image(countries[number])
.renderingMode(.original)
.clipShape(Capsule())
.shadow(radius: 5)
}
}
}.frame(maxWidth: .infinity)
.padding(.vertical, 20)
.background(.thinMaterial)
.clipShape(RoundedRectangle(cornerRadius: 20))
Spacer()
Spacer()
Text("Score: \(score)")
.foregroundColor(.white)
.font(.title.bold())
Spacer()
}.padding()
}
.alert(scoreTitle, isPresented: $showingScore){
Button("Continue", action: askQuestion)
} message: {
if scoreTitle == "Correct" {
Text("Your score is \(score)")
}else {
Text("You are wrong, this is the flag of \(selectedFlag)")
}
}
.alert(scoreTitleFinished, isPresented: $showFinalScore){
Button("Reset Game", action: resetScore)
} message:{
if scoreTitleFinished == "Finished"{
Text("Your final score is \(score)")
}}
}
func flagTapped(_ number: Int){
selectedFlag = countries[number]
numberOfQ += 1
if number == correctAnswer && numberOfQ < 4{
scoreTitle = "Correct"
score += 1
showingScore = true
} else if number == correctAnswer && numberOfQ == 4{
scoreTitleFinished = "Finished"
score += 1
showFinalScore = true
} else if numberOfQ == 4{
scoreTitleFinished = "Finished"
showFinalScore = true
} else if numberOfQ < 4{
scoreTitle = "Wrong"
showingScore = true
}
//
}
// Question
func askQuestion(){
countries.shuffle()
correctAnswer = Int.random(in: 0...2)
}
func resetScore(){
score = 0
numberOfQ = 0
countries.shuffle()
correctAnswer = Int.random(in: 0...2)
}
|
|
I'm new in this gathering. I have a few inquiries regarding this gathering. These inquiries are displayed underneath:
My inquiry is about this string. Assuming that you have any data about this string. Kindly statement me and tackle my concern.
|