创建一个@State var area,它基于两个@State var width,一个@State var height

create a @State var area, that is based on two @State var width, an @State var height

如何组合多个状态变量形成另一个?

我想通过一些用户交互更改高度或宽度的值,并相应地更新视图中的所有内容。所以高度或宽度会改变,面积也会改变。

我想它看起来像这样

@State var width: CGFloat = 50.0
@State var height: CGFloat = 100.0


@State var area: CGFloat // somehow equal to width*height

当前的解决方案只是调用一个 func

func area() -> CGFloat {
  width * height
}

不要area@State;只需将其设为计算变量即可:

@State var height: CGFloat = 50.0
@State var width: CGFloat = 100.0
var area: CGFloat {
    width * height
}
var body: some View {
    VStack {
        Text("Width: \(width)")
        Text("Height: \(height)")
        Text("Area \(area)")
        Button(action: {
            self.height *= 2
        }) {
            Text("Double height")
        }
        Button(action: {
            self.width += 10
        }) {
            Text("Add 10 to width")
        }
    }
}

我添加了一些代码来说明如果 widthheight 改变,area 也会改变,因为 widthheight 改变会导致要重绘的视图,因为它们是 @State。由于计算了 area,因此当重绘视图时,area 被确定为更新后的 widthheight 值的乘积。不过,像您在当前解决方案中所说的那样将其作为一个函数来执行也应该可行。

如果您希望 area 成为 @State 以便您可以将其作为 Binding 传递给其他视图,请执行以下操作:

struct ContentView: View {
@State var height: CGFloat = 50.0
@State var width: CGFloat = 100.0
var area: Binding<CGFloat> {
    Binding(get: {
        self.height * self.width
    }) { (newVal) in

    }
}
var body: some View {
    VStack {
        Text("Width: \(width)")
        Text("Height: \(height)")
        Text("Area \(area.wrappedValue)")
        BindingView(num: area)
        BindingView(num: $height)
        Button(action: {
            self.height *= 2
        }) {
            Text("Double height")
        }
        Button(action: {
            self.width += 10
        }) {
            Text("Add 10 to width")
        }
    }
}

struct BindingView: View {
    @Binding var num: CGFloat
    var body: some View {
        Text("Binding number: \(num)")
    }
}

我创建了 BindingView 作为如何以不同方式使用绑定的示例。对于 @State 变量,您可以通过添加 $ 前缀有效地将它们变成 Binding,但是由于区域明确地是 Binding,您不需要 $ .同样要访问 Binding 中的值,您只需执行变量 .wrappedValue.