SwiftUI:将[StringReplacement]移至Observable环境类时Binding报错求助
解决SwiftUI中Observable环境类数组的TextField绑定问题
问题原因
当stringReplacements是@State变量时,ForEach($stringReplacements)会返回Binding<StringReplacement>类型的元素,因此replacement.old能直接作为TextField需要的Binding<String>参数。但移到@Observable的AppManager后,直接遍历appManager.stringReplacements拿到的是普通的StringReplacement实例,其old/new属性是普通String,无法匹配TextField的Binding<String>参数,导致报错。
解决方案
方法1:使用绑定版ForEach(推荐)
直接对appManager.stringReplacements的绑定进行遍历,拿到的元素仍是Binding<StringReplacement>,和之前@State的使用方式一致:
struct ContentView: View { @Environment(AppManager.self) private var appManager var body: some View { VStack { // 使用$appManager.stringReplacements获取绑定数组 ForEach($appManager.stringReplacements) { $replacement in HStack { TextField( "Old", text: $replacement.old ) Text("->") TextField( "New", text: $replacement.new ) } } } } }
方法2:手动创建Binding
如果需要通过索引访问元素,可以手动为每个属性创建Binding:
struct ContentView: View { @Environment(AppManager.self) private var appManager var body: some View { VStack { ForEach(appManager.stringReplacements.indices, id: \.self) { index in HStack { TextField( "Old", text: Binding( get: { appManager.stringReplacements[index].old }, set: { appManager.stringReplacements[index].old = $0 } ) ) Text("->") TextField( "New", text: Binding( get: { appManager.stringReplacements[index].new }, set: { appManager.stringReplacements[index].new = $0 } ) ) } } } } }
说明
@Observable类的属性变更会自动触发视图更新,两种方法都能保证TextField的输入实时同步到AppManager的stringReplacements数组中。- 方法1更简洁,符合SwiftUI的绑定设计思路,优先推荐使用。
内容的提问来源于stack exchange,提问作者Travis M.
相关产品推荐
相关产品推荐

