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

SwiftUI中ForEach遍历Set时TextField输入中断的无@FocusState解决方案问询

问题解决说明

故障原因

  • ForEach使用字符串元素本身作为ID,编辑时元素值变化触发ID变更,SwiftUI会重建对应的TextField视图,直接丢失输入焦点
  • 原有绑定逻辑每输入一个字符就会修改Set,触发列表刷新,进一步导致输入中断

优化实现(无需@FocusState)

核心逻辑是拆分输入状态和数据源更新:编辑过程中输入内容仅存在行视图的本地状态,不修改Set,仅当用户按下回车键确认输入时才同步更新数据源,完全满足等待用户输入完成再更新的需求。

struct ContentView: View {
    @State private var set: Set<String> = ["value1", "value2", "value3", "value4"]
    var body: some View {
        SetforForEachWithBinding(set: $set)
    }
}

struct SetforForEachWithBinding: View {
    @Binding var set: Set<String>
    var body: some View {
        List {
            ForEach(set.sorted(by: <), id: \.self) { element in
                EditableRow(originalValue: element, set: $set)
            }
        }
    }
}

// 单独行视图,管理自身临时输入状态
struct EditableRow: View {
    let originalValue: String
    @Binding var set: Set<String>
    @State private var inputValue: String = ""
    
    var body: some View {
        TextField("Enter value here...", text: $inputValue, onCommit: {
            // 仅用户按下回车键提交时才更新Set
            guard !inputValue.isEmpty, inputValue != originalValue else { return }
            if set.contains(originalValue) {
                set.remove(originalValue)
                set.insert(inputValue)
            }
        })
        .onAppear {
            inputValue = originalValue
        }
    }
}

如果需要支持失去焦点自动同步修改,只需给TextField加上onEditingChanged回调,在编辑状态变为false时执行和onCommit相同的更新逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:24:05