SwiftUI:如何阻止TextField的onSubmit触发时隐藏键盘?
解决SwiftUI TextField按下发送键后不隐藏键盘的问题
在聊天场景中使用SwiftUI的TextField时,设置.submitLabel(.send)将回车键替换为发送键,按下后虽能触发onSubmit发送消息,但会自动隐藏键盘。用@FocusState重新聚焦输入框会出现键盘隐藏后又弹出的卡顿动画,要彻底避免这个问题,可以通过包装原生UITextField来实现。
解决方案:自定义可保持键盘的聊天输入框
直接使用UIKit的UITextField进行封装,通过代理方法拦截发送键的默认行为,阻止键盘收起:
import SwiftUI struct ChatTextField: UIViewRepresentable { let placeholder: String @Binding var text: String let onSend: () -> Void func makeUIView(context: Context) -> UITextField { let textField = UITextField() textField.placeholder = placeholder textField.returnKeyType = .send textField.delegate = context.coordinator return textField } func updateUIView(_ uiView: UITextField, context: Context) { uiView.text = text } func makeCoordinator() -> Coordinator { Coordinator(parent: self) } class Coordinator: NSObject, UITextFieldDelegate { let parent: ChatTextField init(parent: ChatTextField) { self.parent = parent } func textFieldShouldReturn(_ textField: UITextField) -> Bool { // 仅当输入内容非空时执行发送 guard let inputText = textField.text, !inputText.isEmpty else { return false } parent.onSend() parent.text = "" // 发送后清空输入框 // 返回false阻止键盘自动收起 return false } } }
在SwiftUI视图中使用
将自定义的ChatTextField嵌入你的聊天界面,调用发送逻辑:
struct ChatView: View { @State private var draftMessage = "" var body: some View { VStack { // 聊天消息列表区域 Spacer() ChatTextField(placeholder: "Chat...", text: $draftMessage) { sendMessage(content: draftMessage) } .padding(.horizontal) .frame(height: 44) .background(Color(.systemGray6)) .cornerRadius(22) .padding(.bottom, 16) } } private func sendMessage(content: String) { // 这里实现你的消息发送逻辑,比如发送到服务器、添加到本地列表 print("发送消息:\(content)") } }
原理说明
SwiftUI原生TextField的onSubmit触发时,会自动调用resignFirstResponder()让输入框失去焦点,导致键盘隐藏。而通过封装UITextField,我们在textFieldShouldReturn代理方法中返回false,直接跳过了系统默认的键盘收起逻辑,同时执行发送动作,键盘会保持弹出状态,完全避免了动画卡顿问题。
内容的提问来源于stack exchange,提问作者Sajjon
相关产品推荐
相关产品推荐

