Reputation: 201
First of all, I'm sorry that my English is not perfect.
I want to show a different image depending on the condition of the value received through the return key in the Textfield. I searched and tried several ways, but couldn't find the right way. I couldn't find a proper retrurn key event in SwiftUI, so I tried onReceive.
swift file.
struct QuestionItemView: View {
@State private var question: Question?
@State private var answer = ""
var body: some View {
VStack(spacing: 30) {
GroupBox {
if let question = question {
Text(question.question)
.font(.largeTitle)
.fontWeight(.heavy)
.scaledToFit()
.frame(width: 300, height: 100)
.cornerRadius(12)
}
}
GroupBox {
TextField("Enter your answer", text: $answer)
.frame(width: 300)
.font(.title2)
.scaledToFit()
.cornerRadius(12)
.multilineTextAlignment(.center)
}
onReceive(answer.publisher) { _ in
if answer == question?.answer {
// Image(systemName: "circle")
print("o")
} else {
// Image(systemName: "multiply")
print("x")
}
}
} //: VStack
.frame(width: 240)
.background(RoundedRectangle(cornerRadius: 7.0).fill(Color.white))
.onAppear {
let questions: [Question] = Bundle.main.decode("questions.json")
question = questions.randomElement()
}
}
}
json.file
[
{
"id" : 1,
"question" : "2 X 6",
"answer" : "12"
},
{
"id" : 2,
"question" : "7 + 8",
"answer" : "15"
},
{
"id" : 3,
"question" : "9 - 1",
"answer" : "8"
},
{
"id" : 4,
"question" : "4 / 2",
"answer" : "2"
},
{
"id" : 5,
"question" : "10 X 2",
"answer" : "20"
}
]
Upvotes: 17
Views: 18457
Reputation: 36304
you could try something like this:
struct QuestionItemView: View {
@State private var question: Question?
@State private var answer = ""
@State private var imgType = ""
var body: some View {
VStack(spacing: 30) {
GroupBox {
if let question = question {
Text(question.question)
.font(.largeTitle)
.fontWeight(.heavy)
.scaledToFit()
.frame(width: 300, height: 100)
.cornerRadius(12)
}
}
GroupBox {
TextField("Enter your answer", text: $answer)
.frame(width: 300)
.font(.title2)
.scaledToFit()
.cornerRadius(12)
.multilineTextAlignment(.center)
.onSubmit { // <--- only on pressing the return key
// .onChange(of: answer) { _ in // <-- as you type
// .onReceive(answer.publisher) { _ in // <-- as you type
if answer == question?.answer {
imgType = "circle"
print("o")
} else {
imgType = "multiply"
print("x")
}
}
}
if imgType == "circle" {
Image(systemName: "circle")
} else {
Image(systemName: "multiply")
}
}
.frame(width: 240)
.background(RoundedRectangle(cornerRadius: 7.0).fill(Color.white))
.onAppear {
let questions: [Question] = Bundle.main.decode("questions.json")
question = questions.randomElement()
}
}
}
If you are on an older system, you may need to do this:
TextField("Enter your answer", text: $answer, onCommit: {
if answer == question?.answer {
imgType = "circle"
print("o")
} else {
imgType = "multiply"
print("x")
}
})
Upvotes: 25