如何在带有 Swift 的嵌套视图的 ForEach 语句中实现双向绑定?

How to implement a two-way binding in a ForEach statement with nested views with Swift?

我在 Foreach 语句中实现了双向绑定,似乎 工作正常:

struct ContentView: View {
    @ObservedObject var dataManager: ContentViewModel
    var body: some View {
        ScrollView(.horizontal, showsIndicators: false){
            HStack(spacing: 20){
                ForEach($dataManager.data) { $item in 
                    if item.status == true {
                        Button(item.tag){
                            item.status.toggle()
                        }
                        .foregroundColor(.white)
                        .background(Color.red)
                    } else {
                        Button(item.tag){
                            item.status.toggle()
                        }
                        .foregroundColor(.white)
                        .background(Color.blue)
                    }
                }
            }
        }
    }
}

问题 是当我必须使用一些嵌套视图时,例如:

struct ContentView: View {
    @ObservedObject var dataManager: ContentViewModel
    var body: some View {
        
        ScrollView(.horizontal, showsIndicators: false){
            HStack(spacing: 20){
                ForEach($dataManager.data) { $item in
                    if item.status == true {
                        DetailView(dataManager: dataManager, item: item)
                            .foregroundColor(.white)
                            .background(Color.red)
                    } else {
                        Button(item.tag){
                            item.status.toggle()
                        }
                        .foregroundColor(.white)
                        .background(Color.blue)
                    }
                }
            }
        }
    }
}

和:

struct DetailView: View {
    
    @ObservedObject var dataManager: ContentViewModel
    var item: SMTTagBoardItem
    
    var body: some View {
        Button(item.tag){
            item.status.toggle()
        }
    }
}

struct DetailView_Previews: PreviewProvider {
    static var previews: some View {
        DetailView(dataManager: ContentViewModel(), item: SMTTagBoardItem(id: UUID(), tag: "tag1", rank: 0, status: true))
    }
}

我收到此错误:

Cannot use mutating member on immutable value: 'self' is immutable

行:

item.status.toggle() 

如何在通过将值传递给嵌套视图的 ForEach 语句中实现双向绑定?

首先,不使用@ObservedObject,而是使用EnvironmentObject 和StateObject。

然后使用 @Binding var item 而不是 var item。 (我认为dataManager.data是@Published变量)

ContentView

struct ContentView: View {
    @StateObject var dataManager: ContentViewModel
    var body: some View {
   
        ScrollView(.horizontal, showsIndicators: false){
            HStack(spacing: 20){
                ForEach($dataManager.data) { $item in
                    if item.status == true {
                        DetailView(item: $item)
                            .environmentObject(dataManager)
                            .foregroundColor(.white)
                            .background(Color.red)
                    } else {
                        //more code
                    }
                }
            }
        }
    }
}

DetailView

struct DetailView: View {
    
    @EnvironmentObject var dataManager: ContentViewModel
    @Binding var item: SMTTagBoardItem
    
    var body: some View {
        Button(item.tag){
            item.status.toggle()
        }
    }
}