如果父级有更新,则 ObservedObject 无法在 NavigationLink 的目的地上工作
ObservedObject not working on NavigationLink's destination if there are updates on parent
我有两个屏幕,一个主屏幕和一个细节屏幕,细节屏幕有一个具有其状态的 ObservedObject。我还想在 master 上隐藏导航栏并在 detail 上显示它。为此,我将导航栏隐藏状态作为主视图上的 @State 属性 并将其作为绑定变量发送回详细视图。
我遇到的问题是,每当我在详细信息屏幕中更新该变量时,ObservedObject 就会停止工作。
这是重现问题的示例代码:
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"
}
}
}
如果我保持原样,文本将不会更新为 "Worked"。如果我删除行 self.navigationBarHidden = false
,ObservedObject 将正常工作并且文本将更新。
如何实现预期的行为,更新导航栏,同时保持我观察到的对象正常工作?
原因是,
NavigationLink(destination: DetailView(navigationBarHidden: $navigationBarHidden)) {
Text("Go Forward")
}
激活时创建新的 DetailView 等新的 DetailViewModel
尝试
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()
}
}
现在您将模型与 DetailView 共享,它按预期工作(已写)
If I remove the line self.navigationBarHidden = false, the
ObservedObject will work properly and the text will update.
如果删除此行,则不会重新创建 DetailView(View 中没有任何更改)State 不是 View 状态的一部分,它是引用类型,因此 SwiftUI 看不到任何更改,直到某些值是被他们包裹着改变。
我有两个屏幕,一个主屏幕和一个细节屏幕,细节屏幕有一个具有其状态的 ObservedObject。我还想在 master 上隐藏导航栏并在 detail 上显示它。为此,我将导航栏隐藏状态作为主视图上的 @State 属性 并将其作为绑定变量发送回详细视图。
我遇到的问题是,每当我在详细信息屏幕中更新该变量时,ObservedObject 就会停止工作。
这是重现问题的示例代码:
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"
}
}
}
如果我保持原样,文本将不会更新为 "Worked"。如果我删除行 self.navigationBarHidden = false
,ObservedObject 将正常工作并且文本将更新。
如何实现预期的行为,更新导航栏,同时保持我观察到的对象正常工作?
原因是,
NavigationLink(destination: DetailView(navigationBarHidden: $navigationBarHidden)) {
Text("Go Forward")
}
激活时创建新的 DetailView 等新的 DetailViewModel
尝试
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()
}
}
现在您将模型与 DetailView 共享,它按预期工作(已写)
If I remove the line self.navigationBarHidden = false, the ObservedObject will work properly and the text will update.
如果删除此行,则不会重新创建 DetailView(View 中没有任何更改)State 不是 View 状态的一部分,它是引用类型,因此 SwiftUI 看不到任何更改,直到某些值是被他们包裹着改变。