使用 SceneDelegate.toView() 弹出视图
Posted
技术标签:
【中文标题】使用 SceneDelegate.toView() 弹出视图【英文标题】:Popping views using SceneDelegate.toView() 【发布时间】:2020-12-12 13:31:20 【问题描述】:我有一个 UI,您可以在其中导航/推送视图,如下所示: AView -> BView -> CView -> DView
我想弹出几个视图(从 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)
【问题讨论】:
【参考方案1】:这种行为没有错。如果您启动您的应用并显示 AView,您将在控制台中看到它从 A 和 B 打印 init。
这是因为 BView() 已经在您的 AView 中初始化,即使您还没有激活 NavigationLink。
NavigationLink(destination: BView())
因此,此行为并非特定于您的弹回操作,而是在开始时已经发生。如果您担心多次调用 init(),请参阅 Asperi 的 this 解决方案关于多个 init() 的问题
【讨论】:
以上是关于使用 SceneDelegate.toView() 弹出视图的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)