Swiftui 从 SceneDelegate 重定向到另一个视图

问题描述 投票:0回答:1

当打开特定网址时,我们进入此功能

      func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {

我需要转到特定屏幕,我尝试做的是保留 contentView 实例并尝试设置索引表以转到另一个屏幕,但它不起作用,因为 contentView 实例未正确链接

这是我尝试过的:

      class SceneDelegate: UIResponder, UIWindowSceneDelegate {
      var contentView: some View {
    let context = (UIApplication.shared.delegate as! 
    AppDelegate).persistentContainer.viewContext
    // Remplacez cette partie par votre initialisation de ContentView
   return ContentView().environment(\.managedObjectContext, context)
}...


  func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let url = URLContexts.first?.url else {
        return
    }...
                let a = contentView
        if let contentView = (a as? ModifiedContent<ContentView, _EnvironmentKeyWritingModifier<NSManagedObjectContext>>)?.content {
            // Faire quelque chose avec la contentView ici
            contentView.indexTab = 2
        }

我的内容视图

   struct ContentView: View {
    @State public var indexTab = 0 ...

身体:

     var body: some View {
    VStack{
        if(indexTab > -1){
            
            TCTabBar(images: [
                Image(systemName: "house.fill"),
                Image(systemName: "cart.fill"),
                Image(systemName: "heart.fill"),
                Image(systemName: "gear")
            ], tabIndex: indexTab, contentTabs: [
                AnyView(ProductCatalog(products: $items, cart: $cart, favorites: $favorites)),
                AnyView(CartView(items: $cart)),
                AnyView(ProductCatalog(products: $favorites, cart: $cart, favorites: $favorites)),
                AnyView(SettingsView())
            ])
        }
    }.task {
        ContentViewModel.shared.contentView = self
    }

问题是 ContentView 永远不会从 SceneDelegate 更新 我该如何纠正这个问题?

swift swiftui appdelegate uiscenedelegate
1个回答
0
投票

您绝对不想直接引用

contentView
并修改它,因为可以随时重新创建视图。

您应该做的是创建某种 ViewModel 或某种其他类型的对象来保持全局状态(在本例中是您的

indexTab
)。然后,该对象可以符合
ObservableObject
协议并定义
@Published public var indexTab = 0

您可以在 SceneDelegate 中初始化该对象的单个实例,并通过

@EnvironmentObject var stateStore: StateStore

将其传递到您的视图

所以你最终会得到这样的结果。

class StateStore: ObservableObject {
    @Published public var indexTab = 0
}

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
    var stateStore: StateStore = .init()
    
    var contentView: some View {
        return ContentView()
            ...
            .environmentObject(stateStore) // Pass it down via Environment
    }
    
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        guard let url = URLContexts.first?.url else { return }
        ...
        stateStore.indexTab = 2
    }

    struct ContentView: View {
        @EnvironmentObject var stateStore: StateStore // This will traverse environment and find matching object based on type
        
        var body: some View {
            TCTabBar(
                images: [ ... ],
                tabIndex: stateStore.indexTab, // Use published value here
                contentTabs: [ ... ]
            )
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.