[英]ObservedObject not working on NavigationLink's destination if there are updates on parent
I have two screens, a master and a detail, detail has an ObservedObject that has it's state.我有两个屏幕,一个主屏幕和一个细节,细节有一个具有状态的 ObservedObject。 I also want to hide the navigation bar on master and show it on detail.我还想隐藏 master 上的导航栏并详细显示它。 To do that, I have the navigation bar hidden status as a @State property on master view and send it back to the detail view as a Binding variable.为此,我将导航栏隐藏状态作为主视图上的 @State 属性,并将其作为绑定变量发送回详细视图。
The problem I'm having is that whenever I update that variable inside the detail screen, the ObservedObject stops working.我遇到的问题是,每当我在详细信息屏幕内更新该变量时,ObservedObject 就会停止工作。
Here's a sample code that reproduces the issue:这是重现该问题的示例代码:
struct ContentView: View {
@State var navigationBarHidden = true
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: DetailView(navigationBarHidden: $navigationBarHidden)) {
Text("Go Forward")
}
}
.navigationBarTitle("", displayMode: .inline)
.navigationBarHidden(navigationBarHidden)
.onAppear { self.navigationBarHidden = true }
}
}
}
class DetailViewModel: ObservableObject {
@Published var text = "Didn't work"
}
struct DetailView: View {
@Binding var navigationBarHidden: Bool
@ObservedObject var viewModel = DetailViewModel()
var body: some View {
VStack {
Text(viewModel.text)
}.onAppear {
self.navigationBarHidden = false
self.viewModel.text = "Worked"
}
}
}
If I leave it as is, the text will not update to "Worked".如果我保持原样,文本将不会更新为“工作”。 If I remove the line self.navigationBarHidden = false
, the ObservedObject will work properly and the text will update.如果我删除self.navigationBarHidden = false
,则 ObservedObject 将正常工作并且文本将更新。
How can I achieve the expected behavior, update the navigation bar while keeping my observed object working?我怎样才能达到预期的行为,在保持我观察到的对象工作的同时更新导航栏?
The reason is, that原因是,那
NavigationLink(destination: DetailView(navigationBarHidden: $navigationBarHidden)) {
Text("Go Forward")
}
create new DetailView and so on new DetailViewModel when activating激活时创建新的 DetailView 等新的 DetailViewModel
try尝试
import SwiftUI
struct ContentView: View {
@State var navigationBarHidden = true
@ObservedObject var viewModel = DetailViewModel()
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: DetailView(navigationBarHidden: $navigationBarHidden).environmentObject(viewModel)) {
Text("Go Forward")
}
}
.navigationBarTitle("", displayMode: .inline)
.navigationBarHidden(navigationBarHidden)
.onAppear { self.navigationBarHidden = true }
}
}
}
class DetailViewModel: ObservableObject {
@Published var text = "Didn't work"
}
struct DetailView: View {
@Binding var navigationBarHidden: Bool
@EnvironmentObject var viewModel: DetailViewModel
var body: some View {
VStack {
Text(viewModel.text)
}.onAppear {
self.navigationBarHidden = false
self.viewModel.text = "Worked"
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Now you share the model with DetailView and it works as expected (written)现在您与 DetailView 共享模型,它按预期工作(编写)
If I remove the line self.navigationBarHidden = false, the ObservedObject will work properly and the text will update.如果我删除 self.navigationBarHidden = false 行,ObservedObject 将正常工作并且文本将更新。
If you remove this line, the DetailView in not recreated (there is nothing changed in View) State is not part of View state, it is reference type, so SwiftUI don't see any changes until some values which are wrapped by them change.如果删除此行,则不会重新创建 DetailView(View 中没有任何更改)状态不是 View 状态的一部分,它是引用类型,因此 SwiftUI 不会看到任何更改,直到由它们包装的某些值发生更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.