不知什么原因。到达堆栈的第四个子元素后,显示第三个子元素的绑定被重置。这里的问题是你不能再回去了。
这个问题会延续到第 5 个孩子身上 - 因此重置第 4 个孩子。
我什至试图从根注入一个环境对象,希望能缓解这个问题,但还是一样。
请尝试使用以下代码进行复制。
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var globalEnvironment = GlobalEnviroment()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let contentView = ContentView().environmentObject(globalEnvironment)
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
// other callbacks
}
然后对于视图,我添加了日志记录,以便于查看问题
import SwiftUI
class GlobalEnviroment: ObservableObject {
@Published var isPage2Active = false {
didSet {
print("? [2] something set this to \(isPage2Active)")
}
}
@Published var isPage3Active = false {
didSet {
print("? [3] something set this to \(isPage3Active)")
}
}
@Published var isPage4Active = false {
didSet {
print("? [4] something set this to \(isPage4Active)")
}
}
@Published var isPage5Active = false {
didSet {
print("? [5] something set this to \(isPage5Active)")
}
}
}
struct ContentView: View {
@State private var isDetailActive = false
@EnvironmentObject var env: GlobalEnviroment
var body: some View {
print("? [root] redrawing...")
return NavigationView {
VStack {
NavigationLink(destination: Page2(isActive: $env.isPage2Active)
.environmentObject(env),
isActive: $env.isPage2Active) {
EmptyView()
}
Button(action: {
env.isPage2Active = true
}, label: {
Text("Next")
})
}
}
.onReceive([env.isPage2Active].publisher.first(), perform: { response in
print("? 2: \(response)")
})
.onReceive([env.isPage3Active].publisher.first(), perform: { response in
print("? 3: \(response)")
})
.onReceive([env.isPage4Active].publisher.first(), perform: { response in
print("? 4: \(response)")
})
.onReceive([env.isPage5Active].publisher.first(), perform: { response in
print("? 5: \(response)")
})
.onAppear {
print("? ============================================ >>>> ")
print("? [root] appeared")
}
.onDisappear {
print("? [root] disappear")
print("? <<<< ============================================ ")
}
}
}
struct Page2: View {
@Binding var isActive: Bool
@State private var isDetailActive = false
@EnvironmentObject var env: GlobalEnviroment
var body: some View {
print("? [2] redrawing...")
return VStack {
Text("Page 2")
.padding()
NavigationLink(destination: Page3(isActive: $env.isPage3Active)
.environmentObject(env),
isActive: $env.isPage3Active) {
EmptyView()
}.isDetailLink(true)
Button(action: {
env.isPage2Active = false
}, label: {
Text("Back")
})
.padding()
Button(action: {
env.isPage3Active = true
}, label: {
Text("Next")
})
}
.navigationBarBackButtonHidden(true)
.onAppear {
print("? ============================================ >>>> ")
print("? [2] appeared")
}
.onDisappear {
print("? [2] disappear")
print("? <<<< ============================================ ")
}
}
}
struct Page3: View {
@Binding var isActive: Bool
@EnvironmentObject var env: GlobalEnviroment
var body: some View {
print("? [3] redrawing...")
return VStack {
Text("Page 3")
.padding()
NavigationLink(destination: Page4(isActive: $env.isPage4Active)
.environmentObject(env),
isActive: $env.isPage4Active) {
EmptyView()
}.isDetailLink(true)
Button(action: {
print("ikaw??")
env.isPage3Active = false
}, label: {
Text("Back")
})
.padding()
Button(action: {
env.isPage4Active = true
}, label: {
Text("Next")
})
}
.navigationBarBackButtonHidden(true)
.onAppear {
print("? ============================================ >>>> ")
print("? [3] appeared")
}
.onDisappear {
print("? [3] disappear")
print("? <<<< ============================================ ")
}
}
}
struct Page4: View {
@Binding var isActive: Bool
@State private var isDetailActive = false
@EnvironmentObject var env: GlobalEnviroment
var body: some View {
print("? [4] redrawing...")
return VStack {
Text("Page 4")
.padding()
NavigationLink(destination: Page5(isActive: $env.isPage5Active)
.environmentObject(env),
isActive: $env.isPage5Active) {
EmptyView()
}.isDetailLink(true)
Button(action: {
env.isPage4Active = false
}, label: {
Text("Back")
})
.padding()
Button(action: {
env.isPage5Active = true
}, label: {
Text("Next")
})
}
.navigationBarBackButtonHidden(true)
.onAppear {
print("? ============================================ >>>> ")
print("? [4] appeared")
}
.onDisappear {
print("? [4] disappear")
print("? <<<< ============================================ ")
}
}
}
struct Page5: View {
@Binding var isActive: Bool
@EnvironmentObject var env: GlobalEnviroment
var body: some View {
print("? [5] redrawing...")
return VStack {
Spacer()
Button(action: {
env.isPage5Active = false
}, label: {
Text("Back")
})
.padding()
Text("Page 5")
.padding()
Spacer()
}
.navigationBarBackButtonHidden(true)
.onAppear {
print("? ============================================ >>>> ")
print("? [5] appeared")
}
.onDisappear {
print("? [5] disappear")
print("? <<<< ============================================ ")
}
}
}
答案 0 :(得分:0)
@Binding
在深度嵌套的视图中似乎不可靠,尤其是在 5 级层次结构中。
看起来 isActive
参数在多个嵌套视图中也不可靠。
一种可能的解决方法是使用 @Environment(\.presentationMode)
- 这样即使 Binding
被重置,您仍然可以转到上一个视图:
struct Page4: View {
@Environment(\.presentationMode) private var presentationMode // add this
@EnvironmentObject var env: GlobalEnviroment
var body: some View {
print("? [4] redrawing...")
return VStack {
Text("Page 4")
.padding()
NavigationLink(destination: Page5()
.environmentObject(env),
isActive: $env.isPage5Active) {
EmptyView()
}.isDetailLink(true)
Button(action: {
env.isPage4Active = false
presentationMode.wrappedValue.dismiss() // dismiss to go to the previous view
}, label: {
Text("Back")
})
.padding()
Button(action: {
env.isPage5Active = true
}, label: {
Text("Next")
})
}
.navigationBarBackButtonHidden(true)
.onAppear {
print("? ============================================ >>>> ")
print("? [4] appeared")
}
.onDisappear {
print("? [4] disappear")
print("? <<<< ============================================ ")
}
}
}
(仅针对一个视图添加,但显然它应该在每个视图的 dismiss 操作中)。