#swift #swiftui #desktop-application #xcode12 #macos-big-sur
#swift #свифтуи #desktop-приложение #xcode12 #macos-big-sur #swiftui
Вопрос:
Я пытаюсь создать приложение, которое отображается только в строке меню macOS Big Sur (верхний правый угол), следуя этому руководству: https://medium.com/@acwrightdesign/creating-a-macos-menu-bar-application-using-swiftui-54572a5d5f87/. Это работало на Xcode 11 и macOS Catalina, потому что был файл AppDelegate.swift, но я слышал, что это было заменено этим методом:
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Однако первые несколько шагов руководства требуют, чтобы я внес несколько изменений в (в настоящее время несуществующий) Файл AppDelegate.swift. Я пытался внести эти изменения в MyApp.swift, но, похоже, у меня не получается заставить его работать. Кто-нибудь хочет помочь мне адаптировать это руководство для macOS Big Sur / Xcode 12?
Примечание: вот как должен был выглядеть файл AppDelegate.swift (если он существовал) в соответствии с руководством (если вы по какой-либо причине не хотите открывать руководство):
import Cocoa
import SwiftUI
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var popover: NSPopover!
var statusBarItem: NSStatusItem!
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()
// Create the popover
let popover = NSPopover()
popover.contentSize = NSSize(width: 400, height: 500)
popover.behavior = .transient
popover.contentViewController = NSHostingController(rootView: contentView)
self.popover = popover
// Create the status item
self.statusBarItem = NSStatusBar.system.statusItem(withLength: CGFloat(NSStatusItem.variableLength))
if let button = self.statusBarItem.button {
button.image = NSImage(named: "Icon")
button.action = #selector(togglePopover(_:))
}
}
@objc func togglePopover(_ sender: AnyObject?) {
if let button = self.statusBarItem.button {
if self.popover.isShown {
self.popover.performClose(sender)
} else {
self.popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
}
}
}
}
Комментарии:
1. Вы все равно можете создать AppDelegate вместо использования нового жизненного цикла SwiftUI. Оно даже не устарело.
Ответ №1:
В вашем приложении используйте оболочку свойств NSApplicationDelegateAdaptor, чтобы сообщить SwiftUI, что он должен использовать ваш класс AppDelegate для делегирования приложения. Итак, ваш класс приложения должен выглядеть следующим образом:
@main
struct MyApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Комментарии:
1. Полное решение см. В этом репозитории .