Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI 2: the way to open view in new window

Lets imagine that I have an App

var storeVM = BookStoreViewModel(bla1: bla1, bla2: bla2, bla3: bla3)

@SceneBuilder var body: some Scene {
    WindowGroup {
        BookStoreView( model: storeVM )
    }
    
    #if os(macOS)
    Settings {
        SettingsView(model: config)
    }   
    #endif
}

BookStore have a Grid with a lot of books saved in some DB.

BookView can be initiated by a following way:

BookView(model: bookViewModel)

Target: to open BookView IN A NEW SEPARATED WINDOW(as example by click on the button). How can I do this?


Bonus question: How can I open SettingsView(model: config) from the code?


PS: NavigationLink is not solution for me because I not using the NavigationView.

like image 686
Andrew Avatar asked Jul 15 '20 12:07

Andrew


People also ask

How do I add a view in SwiftUI?

To get started, you'll create a new custom view to manage your map. Choose File > New > File, select iOS as the platform, select the “SwiftUI View” template, and click Next. Name the new file MapView. swift and click Create.

How do I get Windows on SwiftUI?

To actually present a new window, we'll need to add another WindowGroup scene to the app's body property. The new scene will indicate that it expects to receive a value of type Note.ID . We'll also make sure, that the main scene and the detail scene get passed the shared data store as an environment object.

What is navigation view SwiftUI?

NavigationView allows a hierarchical way of moving from one view to another. This includes going back to the previously navigated ones. It's an important component of SwiftUI since the majority of applications have multiple screens for presenting its functionality.


1 Answers

I found this answer, which worked for me in terms of being able to open a new window: https://developer.apple.com/forums/thread/651592?answerId=651132022#651132022

I'm on xcode 12.3, Swift 5.3, running Big Sur.

The following is an example of how to set things up so a button in the ContentView can be used to open the OtherView window.

@main
struct testApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        WindowGroup("OtherView") {
            OtherView()
        }
        .handlesExternalEvents(matching: Set(arrayLiteral: "*"))
    }
}

struct ContentView: View {
    @Environment(\.openURL) var openURL

    var body: some View {
       Button("Other View") {
           if let url = URL(string: "test://otherview") {
               openURL(url)
           }
       }
    }
}

struct OtherView: View {
    var body: some View {
        Text("Other View!")
    }
}

Note: Make sure to follow the URL Scheme instructions included in the linked answer (quoted here for convenience):

Now in Project->Info->URL Types type in test in the URL Schemes field (and the identifier field too) to register our app with the system.

I achieved this by editing the Info.plist file and making the additions there, i.e URL types -> URL Schemes...:

Info.plist

like image 139
hillmark Avatar answered Oct 12 '22 14:10

hillmark