macosswiftuisettings

SwiftUI on MacOS - create Settings with WindowGoup


I am creating settings window for my macOS app, using SwiftUI. I should use Settings {...} scene, however I have found some strange behaviour there. For example I can't make window resizable with any .windowResizability() modifier, or my toolbar is always separated from window titlebar, regardless of ToolbarItem(placement:) I use. If I change Settings to WindowGroup, everything works as expected, but not with Settings.

My App, just for illustration:

var body: some Scene {
        WindowGroup {
                Text("Main window")
                .frame(minWidth: 400, maxWidth: 400, minHeight: 200, maxHeight: .infinity)
        }

        Settings {
                SettingsContentView()
                        .frame(minWidth: 600, maxWidth: 600, minHeight: 200, maxHeight: .infinity)
                        .stdEnvironment(model: self.Model)
        }
        .windowToolbarStyle(.unified)
        .defaultSize(width: 600, height: 500)
        .windowResizability(.contentMinSize)
}

So my question is - if I create settings window using WindowGroup, how do I then connect it to standard Settings command from menu? Is it possible to always open specified WindowGroup whenever settings would normally be opened?


Solution

  • You can use CommandGroup(replacing: .appSettings) { ... } to add a menu item to where the settings menu item would have been. Put your own "Settings" button there to open a regular Window.

    I wouldn't use a WindowGroup for settings, because usually you can only open one settings window.

    Example:

    @Environment(\.openWindow) var openWindow
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .commands {
            CommandGroup(replacing: .appSettings) {
                Button("Settings...") {
                    openWindow(id: "settings")
                }
                .keyboardShortcut(",")
            }
        }
        Window("Settings", id: "settings") {
            Text("Some Settings Here...")
        }
    }