【问题标题】:Understanding Scene/WindowGroup in SwiftUI 2?了解 SwiftUI 2 中的场景/窗口组?
【发布时间】:2020-07-11 16:03:30
【问题描述】:

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

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

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

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

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

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

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

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

  3. 为什么我们需要 WindowGroup?不就是一组View吗?

  4. 一般如何使用它们?

或者我可以阅读比文档或WWDC 1 min video (from 2.00 to 3.05) 更多的详细信息,因为没有足够的信息来理解该主题。

【问题讨论】:

  • @matt 已经检查了 WWDC 2019 - developer.apple.com/videos/wwdc2019 并且我认为与该主题最接近的视频是 developer.apple.com/videos/play/wwdc2019/259 ,但它与 SwiftUI 无关。即便如此,我看了wwdc2020相关的视频,查了官方文档还是不明白,所以才提出这个问题。而且我不明白为什么这是一个糟糕的问题,可以否决或关闭它。
  • @matt 另外,请检查 SwiftUI 文档中标记为“测试版”的“场景”。所以这是 SwiftUI 的新特性。
  • @matt 是的,在第一个视频中,关于 Scene 和 WindowGroup 的时间仅为 65 秒,并提供了一些信息,另一个视频是 15 分钟的关于 DocumentGroup 的视频。两者都没有回答如何正确使用 Scene/WindowGroup。如何打开另一个场景/WindowGroup如何选择显示视图的方式(垂直或水平),如何手动设置显示方式(垂直,水平)[在视频上水平显示,在我的测试项目中-垂直]等等。那里没有相关信息,这就是我在这里问的原因。
  • 我已经观看了 5 次视频,但没有得到任何关于我的问题的答案。
  • 我认为@matt 没有深入研究这一点。乍一看,似乎一切都在那里,但事实并非如此。无论如何,我正在处理同样的问题。运气好的话?我找不到任何关于在 macOS 上显示/隐藏场景或创建单个窗口/场景的文档。

标签: swift macos swiftui scene windowgroup


【解决方案1】:
  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

另一种方法是将displayedScene 设置为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 上的效果真的很差。

【讨论】:

  • 嗨 Andrew,Re 4。 - 它是一个语义容器,有点像 Form 和 List,赋予其中包含的 View 层次结构的一堆标准功能,应该在其间正确运行Apple 的所有平台。目前,对于像独立@StateObjects 这样的 WindowGroup,cmd+N 打开新窗口。未来希望更多。关于 5. 我能找到的半官方指导的最佳来源是今年数字休息室的笔记swiftui-lab.com/random-lessons#window-1。如果发现更好的东西会感兴趣:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-01
  • 2020-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多