从 SwiftUI 中的结构数组更新 @State var Double

Updating a @State var Double from a struct array in SwiftUI

我一整天都在 Whosebug(和 Internet)上寻找使这个按钮起作用的方法,但我没有找到任何东西。

如您所见,我想使用最简单的解决方案在单击按钮时更改值。

代码如下:

// Element.swift

import Foundation
import SwiftUI

struct Element: Identifiable {
    let id = UUID()
    @State var value: Double
    let title: String
}

let elements = [
    Element(value: 10, title: "This is a title"),
    Element(value: 100, title: "This is another title")
]
// ElementView.swift

import SwiftUI

struct ElementView: View {

    let element: Element

    var body: some View {
        HStack {
            Text(element.title)
            Text("\(element.value)")
            Button("More", action: { element.value += 10 })
        }
    }

}

struct ElementView_Previews: PreviewProvider {
    static var previews: some View {
        ElementView(element: elements[0])
    }
}
// ContentView.swift

import SwiftUI

struct ContentView: View {

    var body: some View {
        VStack {
            ForEach(elements) { element in
                ElementView(element: element)
            }
        }
    }

}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

令人惊讶的是,我对 Xcode 没有任何问题。

我错过了什么?提前致谢! :P

您在处理状态方面存在一些问题。通常,在 SwiftUI 中,状态由父级持有并通过绑定传递给子级。同样重要的是,@State 用于 View——而不是你的模型。

查看内联评论以了解更改和解释。

struct Element: Identifiable {
    let id = UUID()
    var value: Double //Remove @State here -- @State is for use in a View
    let title: String
}

struct ElementView: View {

    @Binding var element: Element //pass Element via Binding so it is mutable

    var body: some View {
        HStack {
            Text(element.title)
            Text("\(element.value)")
            Button("More", action: { element.value += 10 })
        }
    }

}

struct ElementView_Previews: PreviewProvider {
    static var previews: some View {
        ElementView(element: .constant(Element(value: 10, title: "This is a title"))) //use .constant() for a Binding in a Preview
    }
}

struct ContentView: View {
    @State private var elements = [ //define elements with @State so they are mutable
        Element(value: 10, title: "This is a title"),
        Element(value: 100, title: "This is another title")
    ]
    
    var body: some View {
        VStack {
            ForEach($elements) { $element in //use element binding syntax to get a binding to each item in the array
                ElementView(element: $element)
            }
        }
    }

}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}