在列表中。突变运算符的左侧不可变:"item"是"let"常量



Xcode 12。代码和生命周期是Swiftui.

我看过其他人的相关问题,似乎他们只是把他们的整个项目代码倾倒在这里;从中挑选我需要的东西有点难。所以,我把这个问题分解成一个最简单的例子。

目标是让numberX在我按+键时迭代。

提前感谢!

struct InfoData: Identifiable {
var id = UUID()
var nameX: String
var numberX: Int
}
class ContentX: ObservableObject {
@Published var infoX = [
InfoData(nameX: "Example", numberX: 1)
]
}
struct ContentView: View {
@StateObject var contentX = ContentX()
var body: some View {
List(contentX.infoX) { item in
HStack {
Text("(item.nameX)")
Spacer()
Button("+") {
item.numberX += 1 //Eror shows up here <<
}
Text("(item.numberX)")
}
}
}
}

在您使用的语法中,item是一个不可变的值,正如错误告诉您的那样。你不能改变它,因为它不代表与它来自的数组的真正连接——它只是一个临时可读的副本,在List迭代中使用。

如果你可以升级到Xcode 13,你可以访问ListForEach中的元素绑定语法,让你这样做:

struct ContentView: View {
@StateObject var contentX = ContentX()
var body: some View {
List($contentX.infoX) { $item in //<-- Here
HStack {
Text("(item.nameX)")
Spacer()
Button("+") {
item.numberX += 1
}
Text("(item.numberX)")
}
}
}
}

这给你一个Bindingitem是可变的,允许你改变它的值(s)和反映在原始数组。

在Xcode 13/Swift 5.5之前,你必须定义自己的方式来改变数组中的元素。这是一个解决方案:

class ContentX: ObservableObject {
@Published var infoX = [
InfoData(nameX: "Example", numberX: 1)
]

func alterItem(item: InfoData) {
self.infoX = self.infoX.map { $0.id == item.id ? item : $0 }
}
}
struct ContentView: View {
@StateObject var contentX = ContentX()
var body: some View {
List(contentX.infoX) { item in
HStack {
Text("(item.nameX)")
Spacer()
Button("+") {
var newItem = item
newItem.numberX += 1
contentX.alterItem(item: newItem)
}
Text("(item.numberX)")
}
}
}
}

或者,使用自定义Binding的另一个选项:


class ContentX: ObservableObject {
@Published var infoX = [
InfoData(nameX: "Example", numberX: 1)
]

func bindingForItem(item: InfoData) -> Binding<InfoData> {
.init {
self.infoX.first { $0.id == item.id }!
} set: { newValue in
self.infoX = self.infoX.map { $0.id == item.id ? newValue : $0 }
}
}
}
struct ContentView: View {
@StateObject var contentX = ContentX()
var body: some View {
List(contentX.infoX) { item in
HStack {
Text("(item.nameX)")
Spacer()
Button("+") {
contentX.bindingForItem(item: item).wrappedValue.numberX += 1
}
Text("(item.numberX)")
}
}
}
}

相关内容

  • 没有找到相关文章

最新更新