web-dev-qa-db-ja.com

Swiftui 2でシーン/ウィンドウグループを理解する?

Swiftui 2のようなオブジェクトがいくつかあります scenewindowgroup ある種のシーンとして。

シーンに関連したドキュメントを読んでWWDC2020ビデオを読んだ後は、次のように階層を見ます。

シングルAPP => 1つまたは複数のシーン=>ビューの階層(または数)

各シーンには、ビュー階層のルートビューが含まれており、システムによって管理されるライフサイクルがあります。各シーンはさまざまな方法で表示できます。プラットフォームに依存します。

  1. ウィンドウグループシーンの子供が少ない場合 - それがそれらを表示する方法を選択する方法? (垂直/水平方向)?手動でコントロールする方法

私のテストプロジェクトのためにこれがHSTACKとVSTACKで制御されていることはわかりません。

  1. シーンが表示される方法は?サンプルアプリには2つのシーンがあります - 2つのビューを持つ各ウィンドウグループ。 MacOSの同じウィンドウで、あるシーンから別のシーンに切り替えるにはどうすればいいですか?

  2. Swiftuiを使って新しいウィンドウで2番目のシーンを開く方法は?

  3. なぜウィンドウグループがまったく必要なのですか?それはただのビューのセットではありませんか?

  4. 一般的にそれらを扱う方法は?

またはドキュメントに書かれているよりも詳細を読むことができる場所、または 2.00から3.05のビデオ(2.00から3.05まで トピックを理解するのに十分な情報がないため。

10
Andrew
  1. それでもそれがそれらを表示する方法をどのように選択するかはわかりません
  2. これを行う簡単な方法はありません。スーパービューを作成し、子ビューを変更する必要があります。 sthのようです:
    @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を変更することです。

もう1つの方法は、EnvironmentVariableとして展示されていることです。しかし、この場合は、ウィンドウのインスタンスが1つだけ正しく動作できます。だからこれは悪い方法です。しかし、誰かにとって大丈夫かもしれません。

  1. Swiftuiを使って新しいウィンドウで2番目のシーンを開く方法は? - これをする簡単な方法はありません。 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. なぜウィンドウグループがまったく必要なのですか?それはただのビューのセットではありませんか? - まさにこのビューを区切りウィンドウとして表示できるように、Swiffiuiに言う。

  2. 一般的にそれらを扱う方法は? - ハックがたくさんだけ。 SwiffiiはMacOSで本当に悪い機能のようです。

1
Andrew