swift - swiftui为什么不能分配可选?
问题描述
为什么不能分配可选?
索引已分配,但仍不显示值
帮帮我,谢谢!
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")
}
}
}
}
Xcode 版本 12.0 测试版 2
解决方案
SwiftUI 依赖于导致getter 在更改时重新计算的@State
变量。body
为此,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)}
}
}
我们更改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)}
}
}
现在你的代码可以工作了!当然,我们也在界面中显示了不需要的 Text,但重点是,简单明了Text(message)
,而不是在闭包中,足以导致整个getter 在更改body
时重新计算。message
因此,我们已经正确解释了您所询问的现象。
那么真正的解决方案是什么?我们如何在不向界面添加额外的 Text 的情况下让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)}
}
}
通过包含message
在闭包的捕获列表中,我们使body
getter 依赖于message
变量,现在代码的行为符合预期。
推荐阅读
- discord - 检查消息是否有 7 个字母,然后发送到频道
- python - 使用 genfromtxt() 和转换器导入 csv
- c# - 没有按钮的弹出窗口 Xamarin.Forms
- c++ - Azure Function 项目在本地构建和部署,但不是来自 azure dev ops 管道
- c - 是否从 C 标准定义的同一联合中的不同成员分配给联合成员?
- python - 如何调整csv文件的大小
- google-bigquery - 为什么 Apache Beam BigQueryIO 每次运行都使用相同的 JobId?
- javascript - 在新选项卡中打开 Stripe 结帐,而不是重定向到结帐
- kotlin - Kotlin 支持 OptionSet 吗?
- linux - 如何在彼此下一个一个地grep相似的值?