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

iOS16+ SwiftUI实现TextField固定在键盘上的方案求助

iOS16+ 聊天页面输入框适配键盘方案

针对你需要的输入框固定键盘顶部、滚动交互收起键盘的需求,iOS16+ 可以通过SwiftUI原生API实现简洁适配,无需手动监听键盘通知,具体实现如下:

核心实现代码

struct MessageView: View {
    @State private var messages: [String] = (1...50).map { "Message \($0)" }
    @State private var inputText = ""
    
    var body: some View {
        NavigationStack {
            ScrollView {
                LazyVStack(spacing: 16) {
                    ForEach(messages, id: \.self) { message in
                        Text(message)
                            .padding(12)
                            .background(Color.blue.opacity(0.1))
                            .cornerRadius(16)
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .padding(.horizontal)
                    }
                }
                .padding(.bottom, 8) // 避免最后一条消息被输入框遮挡
            }
            .scrollDismissesKeyboard(.interactively)
            .toolbar {
                ToolbarItem(placement: .bottomBar) {
                    HStack(spacing: 8) {
                        TextField("输入消息...", text: $inputText)
                            .textFieldStyle(.roundedBorder)
                        Button("发送") {
                            messages.append(inputText)
                            inputText = ""
                        }
                    }
                    .padding(.horizontal)
                    .padding(.vertical, 8)
                }
            }
            .toolbarPosition(.bottomBar)
            .navigationTitle("聊天")
        }
    }
}

关键逻辑说明

  • 输入框自动吸附键盘顶部:iOS16+ 中,.bottomBar 位置的Toolbar会自动识别键盘状态,键盘弹出时会自动移动到键盘顶部,无需额外处理键盘帧变化。
  • 滚动交互收起键盘:scrollDismissesKeyboard(.interactively) 是iOS16+ 原生API,已内置和iMessage一致的交互逻辑——用户向下滚动消息列表时,键盘会跟随滚动进度逐渐收起,滚动停止后键盘完全隐藏。
  • 避免内容遮挡:给ScrollView内的消息列表添加底部padding,防止最后一条消息被输入框遮挡。

自定义扩展

如果需要添加表情、语音等按钮,直接修改ToolbarItem中的HStack布局即可,比如:

HStack(spacing: 8) {
    Button { /* 表情逻辑 */ } label: {
        Image(systemName: "face.smiling")
    }
    TextField("输入消息...", text: $inputText)
        .textFieldStyle(.roundedBorder)
    Button { /* 语音逻辑 */ } label: {
        Image(systemName: "mic")
    }
    Button("发送") {
        messages.append(inputText)
        inputText = ""
    }
}

内容的提问来源于stack exchange,提问作者Ray

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:02:18