I'm making an app in Swift, where users have to answer a question. Multiple answers can be accepted, so I used a ForEach loop to check for all the answers. However, when I try to toggle a "correct" variable (so the "Correct!" message only shows once), I get an error (see title). The error is shown on line 77: ForEach(0..<data.answer.count, id: .self). Does anyone know how to fix this???
import SwiftUI
struct LocationView: View {
@State private var submit: Bool = false
@State private var guess = ""
@State private var correct = false
var data: Location
var body: some View {
Text(data.question)
.padding()
TextField("Answer", text: $guess)
.padding()
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.green, lineWidth: 2)
)
.padding()
Button(action: {
submit.toggle()
}) {
Text("Submit")
.foregroundStyle(.blue)
.font(.headline)
}
if submit {
ForEach(0 ..< data.answer.count, id: \.self) { answer in
if guess == data.answer[answer] {
correct.toggle()
}
}
if correct {
Text("Correct!")
.foregroundStyle(.green)
.font(.headline)
}
}
}
}
}
#Preview {
let modelData = ModelData()
LocationView(data: modelData.locations[0])
}
ForEach is for creating views from a collection. You have not provided any views inside foreach and it is not the right place just for a calculation.
I have moved the calculation of verifying correct answer and changing submit state to button click action
struct Location {
let question: String
let answer: [String]
}
struct LocationView: View {
@State private var submitted: Bool = false
@State private var guess = ""
@State private var correct = false
var data: Location
var body: some View {
question
answer
submitButton
if submitted {
message
}
}
var question: some View {
Text(data.question)
.padding()
}
var answer: some View {
TextField("Answer", text: $guess)
.padding()
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.green, lineWidth: 2)
)
.padding()
.disabled(!guess.isEmpty && submitted)
}
var submitButton: some View {
Button(action: onSubmit) {
Text("Submit")
.foregroundStyle(.blue)
.font(.headline)
}
}
var message: some View {
Group {
if correct {
Text("Correct!")
.foregroundStyle(.green)
} else {
Text("Wrong")
.foregroundStyle(.red)
}
}
.font(.headline)
.transition(.scale)
}
func onSubmit() {
if !guess.isEmpty {
withAnimation {
submitted = true
verifyAnswer()
}
}
}
func verifyAnswer() {
correct = data.answer.contains(guess)
}
}
#Preview {
LocationView(data: Location(question: "guess number?", answer: ["one", "two", "three"]))
}