You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 01:20:31