Stack Overflow Asked on December 25, 2021
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
.
I have played with code from hillmark's answer and got some better results than his code.
Even if this code is still not the answer, this may be useful for someone.
_
Generlly this code will be useless for you in case you need to work with View based on ViewModel.
But if you need to work with View only - this is a good solution.
@main
struct TestAppApp: App {
var body: some Scene {
WindowGroup {
MainView()
}
// magic here
.handlesExternalEvents(matching: Set(arrayLiteral: Wnd.mainView.rawValue))
WindowGroup {
HelperView()
}
// magic here
.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") {
// magic here
Wnd.mainView.open()
}
Button("Open Other View") {
// magic here
Wnd.helperView.open()
}
}
.padding(150)
}
}
struct HelperView: View {
var body: some View {
HStack {
Text("This is ") + Text("Helper View!").bold()
}
.padding(150)
}
}
}
// magic here
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)
}
}
}
To work with this code you need to have the following:
Answered by Andrew on December 25, 2021
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
...:
Answered by hillmark on December 25, 2021
Try something like the following (just idea - cannot test)
class BookViewModel: ObservableObject {}
class AppState: ObservableObject {
@Published var selectedBook: BookViewModel?
}
@main
struct SwiftUI2_MacApp: App {
@StateObject var appState = AppState()
@SceneBuilder
var body: some Scene {
WindowGroup { // main scene
ContentView()
.environmentObject(appState) // inject to update
// selected book
}
WindowGroup("Book Viewer") { // other scene
if appState.selectedBook != nil {
Book(model: appState.selectedBook)
}
}
}
}
Answered by Asperi on December 25, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP