14

SwiftUI 2 中有几个对象,例如SceneWindowGroup作为某种场景。

在阅读文档并查看与场景相关的 WWDC2020 视频后,我通过以下方式查看层次结构:

单个应用程序 => 一个或多个场景 => 视图层次结构(或几个)

每个场景都包含视图层次结构的根视图,并具有由系统管理的生命周期。每个场景可以以不同的方式显示,具体取决于平台。

  1. 如果 WindowGroup 场景的孩子很少 - 它如何选择显示它们的方式?(垂直/水平)?以及如何手动控制它?

我不确定这是由 HStack 和 VStack 控制的,因为在我的测试项目中,我得到了不同的结果,而不是出于某种原因所期望的。

  1. 如何控制显示的场景?作为示例应用程序有 2 个场景 - 每个 WindowGroup 中有 2 个视图。如何在 macOS 的同一窗口中从一个场景切换到另一个场景?

  2. 如何使用 SwiftUI 在新窗口中打开第二个场景?

  3. 为什么我们需要 WindowGroup?它不只是一组视图吗?

  4. 一般如何与他们合作?

或者我可以阅读比文档或WWDC 1 分钟视频(从 2.00 到 3.05)中所写更多的详细信息,因为没有足够的信息来理解该主题。

4

1 回答 1

3
  1. 仍然不知道它是如何选择显示它们的方式
  2. 没有简单的方法可以做到这一点。您需要在其中创建超级视图并更改子视图。某事喜欢:
    @SceneBuilder var body: some Scene {
        WindowGroup {
            NavigatorView()
        }
    }

    enum DisplayedScene {
        case Browser
        case Status(url: URL)
    }


    struct NavigatorView: View {
        @State var displayedScene = DisplayedScene.Browser

        var body: some View {
            VStack {
                switch(model.displayedScene) {
                case DisplayedScene.Browser:
                    BrowserView(model: browserViewModel, wndId: id)
                case DisplayedScene.Status(let url):
                    VStack {
                        StatusView(url: url, wndId: id)
                    
                        Button("back") { AppCore.signals.send(signal: Signal.TaoGit.Navigator.ShowBrowser(wndId: id) ) }
                    }
                default:
                    Text("ERROR")
                }
            }.transition(.identity)
            .animation(.easeInOut)
        }
    }

所以你需要改变显示的视图就是发送信号来改变displayedScene

另一种方法是将 displayScene 设置为EnvironmentVariable. 但在这种情况下,您将只能正确使用一个窗口实例。所以这是一个不好的方法。但对某人来说可以。

  1. 如何使用 SwiftUI 在新窗口中打开第二个场景?- 没有简单的方法可以做到这一点。你需要使用handlesExternalEvents. 样本:
import SwiftUI

@main
struct TestAppApp: App {
    var body: some Scene {
        WindowGroup {
            MainView()
        }
        .handlesExternalEvents(matching: Set(arrayLiteral: Wnd.mainView.rawValue))
        
        WindowGroup {
            HelperView()
        }
        .handlesExternalEvents(matching: Set(arrayLiteral: Wnd.helperView.rawValue))
    }
}

extension TestAppApp {
    struct MainView: View {
        @Environment(\.openURL) var openURL
        
        var body: some View {
            VStack {
                Button("Open Main View") {
                    Wnd.mainView.open()
                }
                
                Button("Open Other View") {
                    Wnd.helperView.open()
                }
            }
            .padding(150)
        }
    }

    struct HelperView: View {
        var body: some View {
            HStack {
                Text("This is ") + Text("Helper View!").bold()
            }
            .padding(150)
        }
    }
}


enum Wnd: String, CaseIterable {
    case mainView   = "MainView"
    case helperView = "OtherView"
    
    func open(){
        if let url = URL(string: "taotao://\(self.rawValue)") {
            print("opening \(self.rawValue)")
            NSWorkspace.shared.open(url)
        }
    }
}
  1. 为什么我们需要 WindowGroup?它不只是一组视图吗?-- 它告诉 swiftUI 这个视图可以显示为单独的窗口。

  2. 一般如何与他们合作?- 只有很多黑客。看起来 SwiftUI 在 MacOS 上的效果真的很差。

于 2021-01-24T11:19:24.230 回答