Swiftui 使用SceneDelegate.toView()弹出视图

Swiftui 使用SceneDelegate.toView()弹出视图,swiftui,swiftui-navigationview,Swiftui,Swiftui Navigationview,我有一个UI,您可以在其中导航/推送视图,如下所示: AView->B视图->C视图->D视图 我想弹出几个视图(从DView进入BView),而不是将新视图(BView)放在现有堆栈的顶部,我找到了这样做的方法: (UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.toBView() 我不明白的是,当我试图从DView返回到BView时,为什么它会调用CView的init() 以下是我在调试控制台中

我有一个UI,您可以在其中导航/推送视图,如下所示: AView->B视图->C视图->D视图

我想弹出几个视图(从DView进入BView),而不是将新视图(BView)放在现有堆栈的顶部,我找到了这样做的方法:

(UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.toBView()

我不明白的是,当我试图从DView返回到BView时,为什么它会调用CView的init()

以下是我在调试控制台中得到的输出:

AView init
BView init
CView init
DView init
contract.
button pressed
BView init
**CView init**
它为什么调用CView的init(),以及如何避免这种行为

AView.swift:

import SwiftUI

struct AView: View {
    
    init() {
        print("AView init")
    }
    

    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: BView()) {
                    Text("This is View A, now go to View B.")
                }
            }
        }
    }
}

struct BView: View {
    init() {
        print("BView init")
    }
    

    var body: some View {
        NavigationLink(destination: CView()) {
                Text("This is View B, now go to View C.")
        }
    }
}

struct CView: View {
    
    init() {
        print("CView init")
    }
    
    var body: some View {
        NavigationLink(destination: DView()) {
                Text("This is View C, now go to View D.")
        }
    }
}

struct DView: View {
    init() {
        print("DView init")
    }
    
    var body: some View {
        Button(action: {
            print("button pressed")
            (UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.toBView()

        },
               label: {
            Text("Back!")
        })

    }
}
SceneDelegate.swift:

import UIKit
import SwiftUI

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Create the SwiftUI view that provides the window contents.
        let aView =     AView()
        
        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: AView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }
    
    func toBView() {
        let bView = BView()
        window?.rootViewController = UIHostingController(rootView: bView)
    }

}

这种行为没有错。如果启动应用程序并显示AView,您将在控制台中看到它从A和B打印init

这是因为BView()已在AView中初始化,即使您尚未激活NavigationLink

NavigationLink(destination: BView()) {
因此,这种行为并不特定于您的弹出式操作,而是在开始时就已经发生了。如果您想多次调用init(),请参阅Asperi关于多个init()的解决方案