A package for make easier implementing a structure of settings / preferences UI for macOS AppKit-based apps.
The window has preferences-style toolbar and native switching animation. It also supports “Reduce Motion” feature of accessibility.
Set active pane name as a window title automatically when panes are switched.
Display window title with pane name on the Window menu automatically.
Basically, the window only has a close button, but a zoom button is optional for per-pane.
We can use the Escape key ⎋ or ⌘. action to close the window.
The settings Window supports autosave frame via UserDefaults. The last window position can be restored automatically.
On before macOS Ventura, “Settings” was “Preferences”. This module can also support renamed “Settings” after Ventura.
More details of this design (Japanese): macOS Venturaからの新しい“Settings”表記と、旧“Preferences”表記からの移行
-
SettingsWindowWindow for Settings window. -
SettingsWindowControllerWindowController for Settings window. -
SettingsTabViewControllerWindowController’s contentViewController. -
SettingsPaneViewControllerThe base view controller for setting pane. You can use this class to customize your own.
Use SwiftPM.
To set panes of settings window, there are two ways of them.
// First, initialize the SettingsWindowController instance
let settingsWindowController = SettingsWindowController(with: [/*panes*/])
// …like this:
let settingsWindowController = SettingsWindowController(with: [
SettingsPaneViewController(tabName: "General",
tabImage: NSImage(systemSymbolName: "gearshape", accessibilityDescription: nil),
tabIdentifier: "general",
isResizableView: false),
SettingsPaneViewController(tabName: "View",
tabImage: NSImage(systemSymbolName: "eyeglasses", accessibilityDescription: nil),
tabIdentifier: "view",
isResizableView: true),
SettingsPaneViewController(tabName: "Extensions",
tabImage: NSImage(systemSymbolName: "puzzlepiece.extension", accessibilityDescription: nil),
tabIdentifier: "extensions",
isResizableView: false),
SettingsPaneViewController(tabName: "Advanced",
tabImage: NSImage(systemSymbolName: "gearshape.2", accessibilityDescription: nil),
tabIdentifier: "advanced",
isResizableView: false),
])
// That’s all. Then you can show the settings window.
settingsWindowController.showWindow(nil)func set(panes: [SettingsPaneViewController])
func add(panes: [SettingsPaneViewController])
func insert(panes: [SettingsPaneViewController], at index: Int)
func insert(tabViewItem: NSTabViewItem, at index: Int)To remove any pane, use NSTabViewController’s methods.
There are properties of tab item in SettingsPaneViewController.
Default tab name, alias of NSViewController.title.
Icon for a tab.
Should set to a unique name.
This key is used for localizing tab name process automatically.
If you use this, SettingsTabViewController replaces tabName with the localized tab name. You can disable this feature with using a property disablesLocalizationWithTabNameLocalizeKey on SettingsTabViewController.
SettingsPaneViewController has the property isResizableView; setting true to allow window resizing only while the pane is active. The default value is false. Check the Demo implementation and Main Storyboard file.
See LICENSE for details.





