为什么不能分配可选?
索引已分配,但仍未显示值
帮帮我,谢谢!
struct TestView: View {
@State private var index: Int? = nil
@State private var show: Bool = false
var body: some View {
VStack {
Text("Hello, world!")
.onTapGesture {
self.index = 1
self.show = true
print(self.index as Any)
}
}
.fullScreenCover(isPresented: $show) {
if let index = self.index {
Text("value:\(index)")
} else {
Text("not value")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Xcode 12.0 测试版 2
SwiftUI 依赖于@State
导致body
getter 在更改时重新计算的变量。为此,body
getter 必须以某些确定的方式依赖于@State
变量。您的代码中的问题在于它没有。
为了看到这一点,我们可以将您的代码简化为一个更简单的示例:
struct ContentView: View {
@State var message = "Hey"
@State var show: Bool = false
var body: some View {
VStack {
Button("Test") {
message = "Ho"
show = true
}
}
.sheet(isPresented: $show) {Text(message)}
}
}
Run Code Online (Sandbox Code Playgroud)
我们更改message
为 Ho,但是当表出现时,它仍然说 Hey。这是因为没有发生任何事情使body
重新计算。你可能会说:那句话Text(message)
呢?是的,但那是在闭包中;它已经被计算出来,并且message
已经被捕获。
看我说的对不对,message
直接在主界面添加一个Text显示即可:
struct ContentView: View {
@State var message = "Hey"
@State var show: Bool = false
var body: some View {
VStack {
Button("Test") {
message = "Ho"
show = true
}
Text(message)
}
.sheet(isPresented: $show) {Text(message)}
}
}
Run Code Online (Sandbox Code Playgroud)
现在你的代码可以工作了!当然,我们也在界面中显示了不需要的 Text ,但重点是,plain and simple Text(message)
,而不是在闭包中,足以导致整个body
getter 在message
更改时重新计算。所以我们已经正确解释了您所询问的现象。
那么真正的解决方案是什么?我们如何在不向界面添加额外文本的情况下让content
闭包按预期运行?一种方法是这样的:
struct ContentView: View {
@State var message = "Hey"
@State var show: Bool = false
var body: some View {
VStack {
Button("Test") {
message = "Ho"
show = true
}
}
.sheet(isPresented: $show) {[message] in Text(message)}
}
}
Run Code Online (Sandbox Code Playgroud)
通过message
在我们的闭包的捕获列表中包含,我们使body
getter 依赖于message
变量,现在代码按预期运行。
归档时间: |
|
查看次数: |
300 次 |
最近记录: |