SwiftUI中输入单个字符后键盘自动收起问题求助
问题分析与解决方案
核心问题根源
键盘自动收起、输入会话错误的本质原因是ForEach使用了id: \.self。当你在TextField输入字符时,数组内的字符串元素值发生变化,ForEach会将其判定为全新元素,销毁原TextField并重建实例——这直接导致输入焦点丢失、键盘收起,同时触发输入会话相关的错误日志。
解决方案:改用带唯一标识的元素结构
通过创建带固定唯一ID的结构体,让ForEach基于稳定的ID追踪元素,而非依赖易变的字符串内容,就能解决焦点丢失问题。
1. 定义Identifiable结构体
创建遵循Identifiable协议的结构体,每个元素拥有唯一id和可编辑的text:
struct ActItem: Identifiable { let id = UUID() var text: String }
2. 调整状态变量
将原字符串数组替换为结构体数组,初始化时创建带空文本的元素:
@State var acts: [ActItem] = [ActItem(text: "")] @State private var actcount = 1
3. 修改ForEach绑定逻辑
ForEach使用元素的id作为标识,绑定到act.text:
ForEach($acts) { $act in HStack{ TextField("", text: $act.text) } .padding(12) .background(RoundedRectangle(cornerRadius: 15).foregroundStyle(.white)) .overlay(RoundedRectangle(cornerRadius: 14) .stroke(Color.black, lineWidth: 2)) }
4. 调整添加/删除按钮逻辑
操作数组时,添加或移除ActItem实例:
// 添加按钮逻辑 self.acts.append(ActItem(text: "")) // 删除按钮逻辑 acts.removeLast()
完整修改后的代码
import SwiftUI struct ActItem: Identifiable { let id = UUID() var text: String } struct ContentView: View { @State var acts: [ActItem] = [ActItem(text: "")] @State private var actcount = 1 var body: some View { VStack(spacing: 16) { ForEach($acts) { $act in HStack{ TextField("", text: $act.text) } .padding(12) .background(RoundedRectangle(cornerRadius: 15).foregroundStyle(.white)) .overlay(RoundedRectangle(cornerRadius: 14) .stroke(Color.black, lineWidth: 2)) } if actcount != 10 { if actcount == 1 { Button{ self.acts.append(ActItem(text: "")) self.actcount += 1 } label: { Text("Add Act") .frame(maxWidth: .infinity) .padding(6) .overlay(RoundedRectangle(cornerRadius: 12).stroke(Color.black, lineWidth: 2)) } } else { HStack(spacing: 16){ Button{ self.acts.append(ActItem(text: "")) actcount += 1 } label: { Text("Add Act") .frame(maxWidth: .infinity) .padding(6) .overlay(RoundedRectangle(cornerRadius: 12).stroke(Color.black, lineWidth: 2)) } Button{ actcount -= 1 acts.removeLast() } label: { Text("Remove Act") .frame(maxWidth: .infinity) .padding(6) .overlay(RoundedRectangle(cornerRadius: 12).stroke(Color.black, lineWidth: 2)) } } } } } .padding() } }
效果说明
修改后,TextField输入时仅更新对应元素的text值,ForEach通过固定id识别元素,不会重建TextField实例,焦点得以保持,键盘不再自动收起,RTI输入错误也会随之消失。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

