2

I have a macOS app which I'd like to open several instances of in separate windows. For demonstration purposes, I have this tiny example project here:

import SwiftUI @main struct MultipleWindowsApp: App { var body: some Scene { WindowGroup { MyView() .environmentObject(ViewModel()) .frame(minWidth: 200, minHeight: 200) } } } struct MyView: View { @EnvironmentObject var vm: ViewModel var body: some View { Toggle(isOn: $vm.toggleState, label: { Text("Some Toggle") }) } } class ViewModel: ObservableObject { @Published var toggleState = false } 

As it is, a new window created from the menu bar will have a reference to the same ViewModel instance (toggling in one window toggles the other and vice versa). I failed to find a simple answer on how I can have different windows with their own respective viewmodels (please note: I am not handling documents here that need to get saved etc., I am just consuming and visualising an api in my app).

1 Answer 1

1

Here is a snapshot of Apple API documentation

/// Every window created from the group maintains independent state. For /// example, for each new window created from the group the system allocates new /// storage for any ``State`` or ``StateObject`` variables instantiated by the /// scene's view hierarchy. /// /// You typically use a window group for the main interface of an app that isn't /// document-based. For document-based apps, use a ``DocumentGroup`` instead. @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) public struct WindowGroup<Content> : Scene where Content : View { 

so, try the following (cannot test now):

@main struct MultipleWindowsApp: App { var body: some Scene { WindowGroup { MyView() .frame(minWidth: 200, minHeight: 200) } } } struct MyView: View { @StateObject var vm = ViewModel() // << this one !! var body: some View { Toggle(isOn: $vm.toggleState, label: { Text("Some Toggle") }) } } 
Sign up to request clarification or add additional context in comments.

2 Comments

Awesome, exactly, what I was missing, thanks. So I guess if in my real application I want to use the viewmodel instance as an EnvironmentObject, I just inject it one level lower (in this example in MyView). Very helpful, as always!
I got to this solution as well. The issue is you can’t use commands for your app in macOS when you want to use the model.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.