【问题标题】:SwiftUI - Changing struct data set in ForEach?SwiftUI - 更改 ForEach 中的结构数据集?
【发布时间】:2020-06-23 14:12:39
【问题描述】:

我是编程和 SwiftUI 的新手,我正在制作这个应用程序,用户可以在其中选择标记为 A-D 的这些按钮。他们可能会选择超过 1 个,我希望当他们点击按钮时,背景颜色会从灰色变为绿色。但是,如果我将底部代码中的“// Here”替换为

Data.Selected = true
Data.Colour = .green

我收到一条错误消息,提示“无法分配给属性:'Data' 是 'let' 常量”。我明白这意味着什么,但我不知道如何将 Data 更改为 var。我尝试在“数据输入”前键入 var,但出现此错误,而不是“一行上的连续语句必须用 ';' 分隔”。无论如何我可以直接修改数据/按钮数据吗?或者有什么解决方法?

struct Buttons: Hashable {
    var Crit: String
    var Selected: Bool
    var Colour: Color
}

var ButtonsData = [
    Buttons(Crit: "A", Selected: false, Colour: Color(.systemGray4)),
    Buttons(Crit: "B", Selected: false, Colour: Color(.systemGray4)),
    Buttons(Crit: "C", Selected: false, Colour: Color(.systemGray4)),
    Buttons(Crit: "D", Selected: false, Colour: Color(.systemGray4))
]

struct CritView: View {
    
    @Binding var CritBoard: Bool
    @Binding var BackgroundColor: Color
    
    var body: some View {
        ZStack(alignment: .topLeading) {
            
            ScrollView(.vertical, showsIndicators: false) {
                HStack(spacing: 15) {
                    ForEach(ButtonsData, id: \.self) { Data in
                        Button(action: {
                          // HERE
                        }) {
                            Text(Data.Crit)
                                .font(.system(size: 30))
                        }
                        .frame(width: 65, height: 55)
                        .background(Data.Colour)
                        .cornerRadius(10)
                    }
                }
                .padding(.top, 50)
            }
            .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height/8)
            .padding(.bottom, UIApplication.shared.windows.first?.safeAreaInsets.bottom)
            .background(Color(.white))
            .cornerRadius(25)
            
            Button(action: {
                self.CritBoard.toggle()
                self.BackgroundColor = .white
            }) {
                Image(systemName: "xmark").foregroundColor(.black)
            }.padding(25)
        }
    }
}

【问题讨论】:

    标签: struct foreach swiftui


    【解决方案1】:

    这是可能的解决方案 - 创建索引/值元组数组并通过索引修改原始容器中的数据:

    ForEach(Array(ButtonsData.enumerated()), id: \.element) { i, Data in
        Button(action: {
          ButtonsData[i].Selected = true
          ButtonsData[i].Colour = .green
        }) {
            Text(Data.Crit)
                .font(.system(size: 30))
        }
        .frame(width: 65, height: 55)
        .background(Data.Colour)
        .cornerRadius(10)
    }
    

    【讨论】:

    • 感谢您的回答!复制并粘贴您的代码后,没有任何错误,但不幸的是没有工作。问题是,虽然“ButtonsData[i].Colour”确实发生了变化,但“.background(ButtonsData[I].Colour)”却没有,因为它不是@State 变量。我做了一些搜索,发现这篇 Hacking with Swift 文章很有帮助 (hackingwithswift.com/books/ios-swiftui/…)。因此,我添加了“@State private var AllData = ButtonsData”并将“ButtonsData[I].Colour”更改为“self.AllData[i].Colour”。
    【解决方案2】:

    好吧,我不认为很多人实际上会遇到相同/相似的问题,但这是我的工作代码。该代码同时使用了@Aspersi 的答案以及 Hacking with Swift 文章中的代码。 (它可能不是最简化的代码,但至少现在可以工作)

    ForEach(Array(ButtonsData.enumerated()), id: \.element) { i, Data in
        Button(action: {
            self.AllData[i].Selected.toggle()
            if self.AllData[i].Selected == true {
                self.AllData[i].Colour = .green
            } else {
                self.AllData[i].Colour = Color(.systemGray4)
            }
        }) {
            Text(Data.Crit)
                .font(.system(size: 30))
        }
        .frame(width: 65, height: 55)
        .background(self.AllData[i].Colour)
        .cornerRadius(10)
    }
    

    完整代码如下

    struct Buttons: Hashable {
        var Crit: String
        var Selected: Bool = false
        var Colour: Color
    }
    
    var ButtonsData = [
        Buttons(Crit: "A", Selected: false, Colour: Color(.systemGray4)),
        Buttons(Crit: "B", Selected: false, Colour: Color(.systemGray4)),
        Buttons(Crit: "C", Selected: false, Colour: Color(.systemGray4)),
        Buttons(Crit: "D", Selected: false, Colour: Color(.systemGray4))
    ]
    
    struct CritView: View {
        
        @Binding var CritBoard: Bool
        @Binding var BackgroundColor: Color
        
        @State private var AllData = ButtonsData
        
        var body: some View {
            ZStack(alignment: .topLeading) {
                
                ScrollView(.vertical, showsIndicators: false) {
                    HStack(spacing: 15) {
                        ForEach(Array(ButtonsData.enumerated()), id: \.element) { I, Data in
                            Button(action: {
                                self.AllData[i].Selected.toggle()
                                if self.AllData[i].Selected == true {
                                    self.AllData[i].Colour = .green
                                } else {
                                    self.AllData[i].Colour = Color(.systemGray4)
                                }
                            }) {
                                Text(Data.Crit)
                                    .font(.system(size: 30))
                            }
                            .frame(width: 65, height: 55)
                            .background(self.AllData[i].Colour)
                            .cornerRadius(10)
                        }
                    }
                    .padding(.top, 50)
                }
                .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height/8)
                .padding(.bottom, UIApplication.shared.windows.first?.safeAreaInsets.bottom)
                .background(Color(.white))
                .cornerRadius(25)
                
                Button(action: {
                    self.CritBoard.toggle()
                    self.BackgroundColor = .white
                }) {
                    Image(systemName: "xmark").foregroundColor(.black)
                }.padding(25)
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-12-25
      • 1970-01-01
      • 2022-11-15
      • 1970-01-01
      • 1970-01-01
      • 2019-08-21
      • 2021-05-23
      • 1970-01-01
      • 2020-10-24
      相关资源
      最近更新 更多