SwiftUI修改数组元素实现折叠功能时报错如何解决?
错误原因
ForEach遍历数组得到的元素i是只读的let常量,而SysAntpatologicosModel为值类型(结构体),无法直接对常量调用toggle()这类可变方法,需要直接修改@State修饰的原数组。
解决方法
有两种常用实现方案:
方案1:通过索引修改原数组(全版本兼容)
遍历数组索引,点击时直接修改对应下标的元素属性:
ForEach(self.dataSys.indices, id: \.self) { index in let i = self.dataSys[index] HStack{ //MARK: NOMBRE PATOLOGIA1 Text(i.nombre) .modifier(Fonts(fontName: .bold,size: 14)) .foregroundColor(Color("blackColor")) .fixedSize(horizontal: false, vertical: true) .frame(maxWidth: .infinity, alignment: .leading) Button(action: { // 直接修改@State数组对应下标的属性 self.dataSys[index].presente.toggle() }) { // 同步切换上下箭头,交互更合理 Image(systemName: i.presente ? "chevron.up" : "chevron.down") .foregroundColor(Color("grayColor")) } } if i.presente == true { //MARK: FECHA PATOLOGIA 1 DatePicker(selection: self.$datePat, in: Date()..., displayedComponents: .date){ Text("pa2Tittle") .modifier(Fonts(fontName: .bold,size: 14)) .foregroundColor(Color("blackColor")) .fixedSize(horizontal: false, vertical: true) .frame(maxWidth: .infinity, alignment: .leading) } .datePickerStyle(DefaultDatePickerStyle()) .autocapitalization(.none) .padding(8) .foregroundColor(Color("blackColor")) .overlay(RoundedRectangle(cornerRadius: 40).stroke(Color("grayColor"), lineWidth: 1)).background(RoundedRectangle(cornerRadius: 40).fill(Color("whiteColor"))) } }
方案2:使用元素绑定(iOS 13+支持,写法更简洁)
直接对@State数组取绑定值传入ForEach,得到可直接修改的元素绑定对象:
ForEach($dataSys, id: \.idantpat) { $i in HStack{ //MARK: NOMBRE PATOLOGIA1 Text(i.nombre) .modifier(Fonts(fontName: .bold,size: 14)) .foregroundColor(Color("blackColor")) .fixedSize(horizontal: false, vertical: true) .frame(maxWidth: .infinity, alignment: .leading) Button(action: { // 直接修改绑定的元素属性 i.presente.toggle() }) { Image(systemName: i.presente ? "chevron.up" : "chevron.down") .foregroundColor(Color("grayColor")) } } if i.presente == true { //MARK: FECHA PATOLOGIA 1 DatePicker(selection: self.$datePat, in: Date()..., displayedComponents: .date){ Text("pa2Tittle") .modifier(Fonts(fontName: .bold,size: 14)) .foregroundColor(Color("blackColor")) .fixedSize(horizontal: false, vertical: true) .frame(maxWidth: .infinity, alignment: .leading) } .datePickerStyle(DefaultDatePickerStyle()) .autocapitalization(.none) .padding(8) .foregroundColor(Color("blackColor")) .overlay(RoundedRectangle(cornerRadius: 40).stroke(Color("grayColor"), lineWidth: 1)).background(RoundedRectangle(cornerRadius: 40).fill(Color("whiteColor"))) } }
补充注意
当前代码所有展开项共用同一个$datePat状态,修改一个项的日期会导致所有展开项同步变更,建议把日期属性也存入SysAntpatologicosModel,让每个项单独存储自己的日期值。
内容的提问来源于stack exchange,提问作者Laura Ramírez
相关产品推荐
相关产品推荐

