【发布时间】:2021-03-28 19:50:41
【问题描述】:
我正在尝试加载远程资源,因此我使用.onAppear 来执行此操作。但是,当我在视图中使用 if/else 时,它会导致它触发两次。
class FooVM: ObservableObject {
@Published var remoteText: String? = nil
func load() {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.remoteText = "\(Date())"
}
}
}
struct Foo: View {
@StateObject private var vm = FooVM()
var body: some View {
content
.onAppear(perform: vm.load)
}
@ViewBuilder
private var content: some View {
if let text = vm.remoteText {
Text(text)
} else {
Circle()
}
}
}
struct ContentView: View {
var body: some View {
TabView {
Foo()
.tabItem {
Image(systemName: "circle.fill")
Text("Home")
}
}
}
}
编辑:当内容在TabView 中时,它只是复制品。我更新了上面的代码
为什么onAppear(以及load)会触发两次? 实际上,在 Playground 中,它每 2 秒重复触发一次,但在模拟器中只触发两次。
我该如何避免呢?请记住,这是一个简化的示例。
有趣的是,如果不是Text 和Circle 之间的选择,而只是Text 中的不同文本,那么它只会触发一次:
Text(vm.remoteText ?? "loading...")
【问题讨论】:
-
对于 Xcode 12.1 / iOS 14.1
load仅使用提供的代码调用一次。你用的是哪个环境? -
Xcode 12.2 / iOS 14.2
-
我在 12.2 / iOS 14.2 上,也只看到 load 调用过一次。您是否在 Playground 之外的模拟器上尝试过?
-
@nicksarno,是的 - 实际上是在模拟器上尝试
-
好吧,我无法用当前代码重现它。唯一想到的是当内容切换时视图可能会“重新出现”。尝试在 ZStack 中嵌入“内容”并在 ZStack 上调用 .onAppear 。这样在内容重新出现时 ZStack 仍然存在?只是在这里猜测哈哈