SwiftUI 如何监听TextField回车键事件并按输入匹配结果展示不同图标
解决方案
方案1:iOS 15+ 原生实现(推荐)
SwiftUI 从 iOS 15 开始提供了原生的onSubmit修饰符,专门用于监听输入框的回车键触发事件,完全符合你的需求,你可以直接替换原来的onReceive逻辑,步骤如下:
- 新增状态变量控制结果图标的展示
- 给
TextField添加onSubmit修饰符,回车时触发答案校验 - 根据校验结果展示对应图标
修改后的完整代码:
struct QuestionItemView: View { @State private var question: Question? @State private var answer = "" // 新增状态:nil=不显示图标,true=答案正确,false=答案错误 @State private var isAnswerCorrect: Bool? = nil 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 { guard let correctAnswer = question?.answer else { return } // 自动去除输入前后的空格换行,避免输入误判 isAnswerCorrect = (answer.trimmingCharacters(in: .whitespacesAndNewlines) == correctAnswer) // 如果需要回车后清空输入/切换下一题,可以在这里加逻辑 // 例如: // DispatchQueue.main.asyncAfter(deadline: .now() + 1) { // answer = "" // isAnswerCorrect = nil // question = Bundle.main.decode("questions.json").randomElement() // } } } // 展示结果图标 if let result = isAnswerCorrect { Image(systemName: result ? "checkmark.circle.fill" : "xmark.circle.fill") .foregroundColor(result ? .green : .red) .font(.system(size: 60)) } } //: VStack .frame(width: 240) .background(RoundedRectangle(cornerRadius: 7.0).fill(Color.white)) .onAppear { let questions: [Question] = Bundle.main.decode("questions.json") question = questions.randomElement() } } }
方案2:兼容 iOS 15 以下版本
如果需要适配更低系统版本,可以通过桥接 UIKit 的UITextField实现回车键监听,核心是通过UITextFieldDelegate的textFieldShouldReturn方法捕获回车事件,示例封装如下:
struct ReturnKeyMonitorTextField: UIViewRepresentable { @Binding var text: String let placeholder: String let onReturn: () -> Void func makeUIView(context: Context) -> UITextField { let textField = UITextField() textField.placeholder = placeholder textField.text = text textField.delegate = context.coordinator textField.textAlignment = .center return textField } func updateUIView(_ uiView: UITextField, context: Context) { uiView.text = text } func makeCoordinator() -> Coordinator { Coordinator(text: $text, onReturn: onReturn) } class Coordinator: NSObject, UITextFieldDelegate { @Binding var text: String let onReturn: () -> Void init(text: Binding<String>, onReturn: @escaping () -> Void) { self._text = text self.onReturn = onReturn } func textFieldDidChangeSelection(_ textField: UITextField) { text = textField.text ?? "" } func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() onReturn() return true } } }
使用时直接替换原来的TextField即可:
ReturnKeyMonitorTextField(text: $answer, placeholder: "Enter your answer", onReturn: { guard let correctAnswer = question?.answer else { return } isAnswerCorrect = (answer.trimmingCharacters(in: .whitespacesAndNewlines) == correctAnswer) }) .frame(width: 300) .font(.title2)
内容的提问来源于stack exchange,提问作者JeeNi
相关产品推荐
相关产品推荐

