遍历数组中视图(结构)的属性返回错误的值(初始值)

Looping over the properties of Views (struct) in an Array is returning wrong values (init values)

我正在使用一组标签视图来显示带有所有标签的滚动视图。当这些标签被点击时,它们被选中并且标签视图中的 @State 布尔值 属性 被切换。因此在底部单击“提交”按钮时,选定 标签的值将发送到服务器。

在“提交”按钮中,我使用 For-Loop 循环遍历标签视图并检查具有 myLabel.isSelected == true 的标签,但即使在之后所有标签都返回 false被选中。

主视图简化:

struct Sheet: View {
    
    @State var myLabels: [MyLabel] = [
        MyLabel(systemImage: "sparkles", text: "Keine Gebrauchsspuren"),
        MyLabel(systemImage: "checkmark.circle", text: "Minimale Gebrauchsspuren"),
        MyLabel(systemImage: "exclamationmark.circle", text: "Mehrere Gebrauchsspuren"),
        MyLabel(systemImage: "xmark.circle", text: "Starke Gebrauchsspuren"),
        MyLabel(systemImage: "arrow.down.to.line", text: "Delle(n)")

    ]

    var body: some View {
        ScrollView {
              ForEach(myLabels, id: \.self) {label in label}
        }
        Button {
             var combinedString = ""
             for label in myLabels {
                   if label.isSelected {
                           combinedString += label.text 
                   }
             }
             postTextFunc(combinedString)
        } label: {
             Text("Submit")
        }
    }

combinedString 总是返回空,因为当我遍历 myLabels 时,所有标签都将 isSelected 设置为 false。这是因为 SwiftUI 在属性更改时如何处理结构吗?我怎样才能达到我的目标,即只返回提示标签的值?

非常感谢!

视图是 SwiftUI 中的结构。因此将它们传递给函数将创建这些视图的副本。而你正在迭代未修改的原始视图。

我认为 ViewModel/Model 在这里最好。

struct Model: Identifiable{
    var selected: Bool
    let text: String
    let id = UUID()
}

class Viewmodel: ObservableObject{
    @Published var models: [Model] = [] //Create the datamodel here
    
    func select(_ selectedModel: Model){
        var selectedModel = selectedModel
        selectedModel.selected.toggle() //Create a new copy and toggle selection
        
        // get index of selected item
        guard let index = models.firstIndex(where: {[=10=].id == selectedModel.id}) else{
            return
        }
        
        // assign item. This will toggle changes in the view
        models[index] = selectedModel
    }
    
func post(){
    //Create combined string
    let combinedString = models.filter{[=10=].selected}.reduce("") { partialResult, model in
        partialResult + model.text
    }
    //call post
    postTextFunc(combinedString)
}

func postTextFunc(_ string: String){
    
}
}

struct InnerView: View{
@EnvironmentObject private var viewmodel: Viewmodel
var selected: Model // provide the individual data here
var body: some View{
    Text(selected.text)
        .onTapGesture {
            viewmodel.select(selected)
        }
    }
}

struct TestView: View{
    
    @StateObject private var viewmodel = Viewmodel()
    
    var body: some View {
            ScrollView {
                ForEach(viewmodel.models, id: \.id) { model in
                    InnerView(selected: model)
                        .environmentObject(viewmodel) // pass viewmodel in environment
            }
        }
        Button {
            viewmodel.post()
        } label: {
             Text("Submit")
        }
    }
}