JeeNi
JeeNi

Reputation: 201

SwiftUI - Textfield return key event

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

Answers (1)

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

Related Questions