将@State 变量传递给 ContentView
Posted
技术标签:
【中文标题】将@State 变量传递给 ContentView【英文标题】:Pass an @State variable to ContentView 【发布时间】:2021-02-26 07:14:18 【问题描述】:构建我的第一个 SwiftUI 应用程序,但我一直坚持将 @State var 传递给 ContentView。我在一个结构中声明了@State 变量,在 ContentView 中的变量上有一个@Binding 标记。
我的意图是在 ContentView 中调用 NumberBlock 的多个实例,并且能够通过一个按钮将它们全部重置为 false(隐藏所有图像)。
Xcode 12 中添加的新“App”结构会因缺少参数而出错。我已经尝试了所有我能想到的输入参数,但似乎没有任何效果。我可以通过使用 .constant(true) 来消除错误,但这并没有提供我需要的功能,即从 ContentView 切换变量。
感谢任何帮助消除错误或纠正我对@State 和@Binding 的浅薄理解。
这里是我创建@State reset_x var的地方
import SwiftUI
struct NumberBlock: View
@State var reset_x: Bool = true
@Binding var reset: Bool
var body: some View
ZStack
Text("test")
.onTapGesture(count: 1, perform:
self.reset_x = false
)
Image("XMark")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 50, height: 50, alignment: .center)
.onTapGesture(count: 1, perform:
self.reset_x = true
print("reset_x is \(self.reset_x)")
)
.isHidden(reset_x ? true : false)
.isHidden(reset ? true : false)
此视图出现错误:
import SwiftUI
@main
struct Quixx2App: App
var body: some Scene
WindowGroup
ContentView()
这里是我想使用@Binding的地方
import SwiftUI
struct ContentView: View
@State var reset: Bool = false
@Binding var reset_x: Bool
var body: some View
VStack
HStack
NumberBlock(reset: self.$reset)
NumberBlock(reset: self.$reset)
Button("Reset Score")
self.scoreKeeper.redScore = 0
self.reset_x = false //this line is not doing anything
print("reset_x is \(self.reset_x)")
还有 .isHidden 扩展名
import Foundation
import SwiftUI
extension View
@ViewBuilder func isHidden(_ hidden: Bool, remove: Bool = false) -> some View
if hidden
if !remove
self.hidden()
else
self
【问题讨论】:
我说对了吗?如果单击文本视图,则应显示其自己的 NumberBlock 中的图像。如果您单击该图像,它应该再次被隐藏。如果你点击“重置分数”,所有 Numberblocks 中的所有图像都应该被隐藏。 是的,完全正确 【参考方案1】:让我们从您的NumberBlock
视图开始。您需要视图中的一种状态,该状态会保留图像是否隐藏。通过点击文本视图,切换值并相应地呈现视图。
struct NumberBlock: View
@State private var imageIsHidden: Bool
var body: some View
VStack
Text("Show")
.onTapGesture(count: 1, perform:
self.imageIsHidden = false
)
Text("Image")
.onTapGesture(count: 1, perform:
self.imageIsHidden = true
)
.isHidden(imageIsHidden ? true : false)
现在,您需要第二个功能:ContentView
应该控制此状态。所以你必须把这个状态从子视图(NumberBlock
)提取到父视图(ContentView
)。通过将属性从 @State
更改为 @Binding
,您基本上是在告诉子视图此数据是从父视图传递的。
我的工作示例:
import SwiftUI
import Foundation
extension View
@ViewBuilder func isHidden(_ hidden: Bool, remove: Bool = false) -> some View
if hidden
if !remove
self.hidden()
else
self
struct NumberBlock: View
@Binding var imageIsHidden: Bool
var body: some View
VStack
Text("Show")
.onTapGesture(count: 1, perform:
self.imageIsHidden = false
)
Text("Image")
.onTapGesture(count: 1, perform:
self.imageIsHidden = true
)
.isHidden(imageIsHidden ? true : false)
struct ContentView: View
@State var imageOfBlock1IsHidden: Bool = true
@State var imageOfBlock2IsHidden: Bool = true
var body: some View
VStack
HStack
NumberBlock(imageIsHidden: self.$imageOfBlock1IsHidden)
NumberBlock(imageIsHidden: self.$imageOfBlock2IsHidden)
Button("Reset Score")
self.imageOfBlock1IsHidden = true
self.imageOfBlock2IsHidden = true
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
【讨论】:
谢谢,这很有帮助。所以在这种情况下,我会为每个图像创建一个@State var?我认为这会起作用,但总共会有大约 50 张图像,这意味着要管理的变量列表很长。 是的,正确的。如果您的逻辑变得复杂,请考虑引入 ViewModel 是否有意义。但这就像在没有额外信息的情况下在黑暗中刺伤。以上是关于将@State 变量传递给 ContentView的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swiftui 中根据彼此初始化 @State 变量?