SingleWindow is a SwiftUI library for macOS which simplifies standard Mac window operations which may be obscured in pure SwiftUI. Your window hosts a SwiftUI View and has use of traditional operations such as open, close, hide, bring front, set title, etc. which were more direct under AppKit. Hence this library implements them with AppKit calls - explicitly, windows created via this library do not live in the Scene
framework. SingleWindow makes it simple to create a "dashboard" type display of which your app needs exactly 1 (Single) copy, and its contents are preserved when it is closed.
Use SingleWindow for a "dashboard" type window that you need exactly one of, whose contents don't depend on whether its visible or not.
- Create persistent windows for SwiftUI views
- Programmatically open or close windows
- Programmatic control of window zooming
- Access to the underlying AppKit
NSWindow
object - Support for multiple SingleWindow instances (1 dashboard, 1 clock,etc)
- Menu command for toggling window visibility, with optional keyboard shortcuts
- Option to create windows on external displays
- Auto save/restore window positions
- Scroll Wheel handler
- Ability to identify the front window - eg, for directing menu commands
- Optional Key event handler, which catches some keyDowns that get lost via the nuances of SwiftUI focus management
SingleWindow can be installed using the Swift Package Manager. Add the package to your Xcode project by selecting File
> Add Package Dependencies...
and entering the repository URL:
https://github.com/S1D1T1/SingleWindow.git
Create a SingleWindow object to host your SwiftUI view, by calling makeSingleWindow
, passing your View in a closure:
import SingleWindow
// My app needs a groovy clock window
let groovyClockWindow = makeSingleWindow(
title: "Groovy Clock",
shortcutString: "1" // Command-1 toggles the Groovy Clock
) {
GroovyClockView()
}
title:String
The title of the window.external:Bool
Optional boolean indicating whether the window should be opened on an external display, if available. default:falseshortcutString:String
Optional string representing the keyboard shortcut for toggling the window visibility. default: no keyboard shortcutrect:NSRect
Optional initial rectangle for the window.onKey:((_ :NSEvent)->Bool)?
Optional key event handlercontent:() -> V
A closure returning your SwiftUI view to be hosted
isOpen
: A boolean property indicating whether the window is currently open.myWindow
: Direct access to the underlyingNSWindow
object.
open()
: Opens the window.close()
: Closes the window.setWindowTitle(_:String)
: Sets the title of the window.
To add a menu item in the "Window" menu for toggling the visibility of your SingleWindow, call SingleWindowCommandGroup()
within your .commands
block:
.commands {
SingleWindowCommandGroup()
}
(an aside: "Which .commands block", you might ask. Command blocks modify Scenes, and SingleWindow replaces some Scenes. Luckily, commands can apparently be attached to any Scene, to appear in the menu bar. My app hangs its .commands() block off of the "Settings" scene. And what if your app ONLY wants SingleWindows, and has no Scene to hang menu commands from? Good Question. I don't have a general answer)
The menu item will be created with the format "Show/Hide <Your Window Title>
". If a shortcutString
was provided when creating the SingleWindow, the menu item will also have the corresponding keyboard shortcut.
You can also create a SingleWindow on an external display, if available:
let externalSingleWindow = makeSingleWindow(
title: "Groovy Clock, Stage Left",
external: true,
shortcutString: "1" // Command-1 toggles the Groovy Clock
) {
GroovyClockView()
}
Apply a menu command to the front window, by examining your SingleWindow objects, using AppKit properties
// Command-Option-T toggles toolbar on the front window
Button("Toggle Toolbar"){
if appWindowStates.imageBrowserWindow.myWin.isKeyWindow {
ImageBrowserState.shared.showToolbar.toggle()
}
else if appWindowStates.galleryWindow.myWin.isKeyWindow {
GalleryWindowState.shared.showToolbar.toggle()
}
}.keyboardShortcut("t",modifiers: [.command,.option])
SingleWindow is released under the MIT License.