In this simple example app, I have the following requirements:
- have multiple windows, each having it's own
ViewModel
- toggling the
Toggle
in one window should not update the other window's
- I want to also be able to toggle via menu
As it is right now, the first two points are not given, the last point works though. I do already know that when I move the ViewModel
's single source of truth to the ContentView
works for the first two points, but then I wouldn't have access at the WindowGroup
level, where I inject the commands.
import SwiftUI
@main
struct ViewModelAndCommandsApp: App {
var body: some Scene {
ContentScene()
}
}
class ViewModel: ObservableObject {
@Published var toggleState = true
}
struct ContentScene: Scene {
@StateObject private var vm = ViewModel()// injecting here fulfills the last point only…
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(vm)
.frame(width: 200, height: 200)
}
.commands {
ContentCommands(vm: vm)
}
}
}
struct ContentCommands: Commands {
@ObservedObject var vm: ViewModel
var body: some Commands {
CommandGroup(before: .toolbar) {
Button("Toggle Some State") {
vm.toggleState.toggle()
}
}
}
}
struct ContentView: View {
@EnvironmentObject var vm: ViewModel//injecting here will result in window independant ViewModels, but make them unavailable in `ContactScene` and `ContentCommands`…
var body: some View {
Toggle(isOn: $vm.toggleState, label: {
Text("Some State")
})
}
}
How can I fulfill theses requirements–is there a SwiftUI solution to this or will I have to implement a SceneDelegate
(is this the solution anyway?)?
Edit:
To be more specific: I'd like to know how I can go about instantiating a ViewModel for each individual scene and also be able to know from the menu bar which ViewModel is meant to be changed.
question from:
https://stackoverflow.com/questions/65935505/switfui-access-the-specific-scenes-viewmodel-on-macos 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…