はじめに
以前、SwiftUIでメニューバーアプリを作成しました。
この時は公式でサポートされていませんでしたので、NSHostingControllerとNSPopoverを使用して無理やり作っていました。
しかし!!WWDC22でMenuBarExtra
というメニューバーアプリをSwiftUIで作る用の機能が発表されました!!
macOS13がリリースされたので早速使ってみました!
以前の実装方法と比較しながら紹介できたらと思います!
以前の実装方法
import SwiftUI
@main
struct SwiftUI_MenuBar_DemoApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
Settings { }
}
}
class AppDelegate: NSObject, NSApplicationDelegate {
var statusBarItem: NSStatusItem!
var popover = NSPopover()
func applicationDidFinishLaunching(_ notification: Notification) {
popover.behavior = .transient
popover.contentViewController = NSHostingController(rootView: ContentView())
self.statusBarItem = NSStatusBar.system.statusItem(withLength: CGFloat(NSStatusItem.variableLength))
guard let button = self.statusBarItem.button else { return }
// アイコンの設定
button.image = NSImage(systemSymbolName: "camera.macro", accessibilityDescription: nil)
// アクションの設定
button.action = #selector(menuButtonAction(sender:))
}
@objc func menuButtonAction(sender: AnyObject) {
guard let button = self.statusBarItem.button else { return }
if self.popover.isShown {
self.popover.performClose(sender)
} else {
// ポップアップを表示
self.popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
// 他の位置をタップすると消える
self.popover.contentViewController?.view.window?.makeKey()
}
}
}
macOS13からの実装方法
これだけ!!簡単!!!
import SwiftUI
@main
struct MenuBarApp: App {
var body: some Scene {
MenuBarExtra {
ContentView()
} label: {
Image(nsImage: NSImage(named: "menubar"))
}
.menuBarExtraStyle(.window)
}
}
注意1
MenuBarExtra
のlabelにImageを設定する場合はNSImage
でないとライトモードとダークモードでの切り替えがされません
注意2
.menuBarExtraStyle(.window)
これがないとContentView
のサイズで表示されません
おわり
SwiftUIでできることが増えると嬉しいです😆
MenuBarExtraを使ったメニューバーアプリです!
スターください!!!!