SwiftUI's built in MenuBarExtra
API makes it easy to create menu bar applications in pure SwiftUI. However, the current implementation of the WindowMenuBarExtraStyle
is limited in that it doesn't fade out when dismissed like traditional menu items, doesn't persist selection state when the menu is opened, and uses a less-than-ideal resizing mechanism that leaves your app feeling unpolished.
FluidMenuBarExtra is a lightweight package that provides a convenient API for creating seamless menu bar extras with SwiftUI in both AppKit and SwiftUI apps. Once MenuBarExtra is improved in future versions of macOS, switching back to MenuBarExtra is as simple as moving a few lines of SwiftUI code back to your App
.
scenePhase
environment key.To use FluidMenuBarExtra, initialize a FluidMenuBarExtra
once during your app's lifecycle. Multiple instances of FluidMenuBarExtra
can exist if you need more than one menu bar extra.
First, define an application delegate. Don't worry, your app's entry point will still be based in SwiftUI.
class AppDelegate: NSObject, NSApplicationDelegate {
private var menuBarExtra: FluidMenuBarExtra?
func applicationDidFinishLaunching(_ notification: Notification) {
self.menuBarExtra = FluidMenuBarExtra(title: "My Menu", systemImage: "cloud.fill") {
Text("My SwiftUI View")
}
}
}
Then, use the @NSApplicationDelegateAdaptor
property wrapper to attach the delegate to your SwiftUI application:
import SwiftUI
@main
struct MyApplication: App {
@NSApplicationDelegateAdaptor private var appDelegate: AppDelegate
var body: some Scene {
Settings {
SettingsTabs()
}
}
}
That's it! The menu bar extra will be installed as long as the reference to the FluidMenuBarExtra
exists. When the reference is deleted or set to nil
, the item will be removed from the menu bar.
💡 Tip: If any stateful properties or utilities need to be shared between your menu bar extra and other windows, you can move those properties to your
AppDelegate
. To allow SwiftUI views to consume published properties, conform the delegate class toObservableObject
. SwiftUI will then automatically insert the delegate into the environment. Learn more.
Scene
be valid. Because FluidMenuBarExtra is not created in a scene, you'll need at least one other scene in the body of your App
:
Settings
scene with an EmptyView()
inside._EmptyScene()
, but no guarantees that App Review will like it.NSWindow
, not an NSMenu
, you'll find that the window presented by FluidMenuBarExtra has a slighter wider corner radius than other menus.All contributions are welcome. If you have a need for this kind of package, feel free to resolve any issues and add any features that may be useful.
FluidMenuBarExtra is released under the MIT License unless otherwise noted.
link |
Stars: 38 |
Last commit: 7 weeks ago |
Full Changelog: https://github.com/lfroms/fluid-menu-bar-extra/compare/1.0.2...1.1.0
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics