创建一个@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")
}
}
}
我添加了一些代码来说明如果 width
或 height
改变,area
也会改变,因为 width
或 height
改变会导致要重绘的视图,因为它们是 @State
。由于计算了 area
,因此当重绘视图时,area
被确定为更新后的 width
和 height
值的乘积。不过,像您在当前解决方案中所说的那样将其作为一个函数来执行也应该可行。
如果您希望 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
.
如何组合多个状态变量形成另一个?
我想通过一些用户交互更改高度或宽度的值,并相应地更新视图中的所有内容。所以高度或宽度会改变,面积也会改变。
我想它看起来像这样
@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")
}
}
}
我添加了一些代码来说明如果 width
或 height
改变,area
也会改变,因为 width
或 height
改变会导致要重绘的视图,因为它们是 @State
。由于计算了 area
,因此当重绘视图时,area
被确定为更新后的 width
和 height
值的乘积。不过,像您在当前解决方案中所说的那样将其作为一个函数来执行也应该可行。
如果您希望 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
.