长话短说,我的用例是在Mac催化剂应用程序中包含状态栏菜单,为此我需要访问Appkit库。多亏了共享协议的方法,我可以在catalyst应用程序中同时包含Appkit和UIkit,只要它加载默认的NSMenuItem,我就可以加载NSStatubar,但是当我将Custom SwiftUI视图分配给NSMenuItem时,状态栏根本不显示。
下面是我如何在Appdelegate中加载插件的代码
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
let macPlugin = AppKitContainer.loadPlugin()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if let macPlugin = macPlugin {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
macPlugin.loadStatusMenu()
}
}
return true
}
}
下面是我如何用默认nsmenuitem加载状态栏
class MacPlugin: NSObject, Plugin {
var statusBarItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
var menu = NSMenu()
var contentMenuItemView = NSMenuItem.init()
//load default nsmenuitem which works
func loadStatusMenu() {
statusBarItem.button?.title = "search"
menu.addItem(NSMenuItem(title: "Quit Silicon Info", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q"))
statusBarItem.menu = menu
}
}
输出https://i.stack.imgur.com/v4pYO.png
下面是我如何在状态栏中加载SwiftUI视图(基本上用Swiftui视图替换了默认菜单项)
import AppKit
class MacPlugin: NSObject, Plugin {
var statusBarItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
var menu = NSMenu()
var contentMenuItemView = NSMenuItem.init()
//load swiftui in nsmenuitem doesn't work
func loadStatusMenuWithSwiftUIView() {
statusBarItem.button?.title = "search"
let view = NSHostingView.init(rootView: Text.init("Hello world")) //SwiftUI view
view.frame = NSRect(x: 0, y: 0, width: 292, height: 633)
contentMenuItemView.view = view
menu.addItem(contentMenuItemView)
statusBarItem.menu = menu
}
}
输出:未显示状态栏
根据调试,方法不会被调用,它与NSHostingView有关。控制台中没有错误。
任何帮助都很感激。
1条答案
按热度按时间wgxvkvu91#
这不可能IIRC您的AppKit捆绑包只能访问您的主(Catalyst)应用加载的框架,其中包括UIKit、AppKit和 * UIKit兼容版本的SwiftUI*。
NSHostingView
在 * AppKit兼容版本的SwiftUI* 中定义,这是一个单独的框架,并且(AFAIK)无法从Catalyst应用程序访问。您可以创建一个单独的Mac/AppKit应用程序,然后将其与Catalyst应用程序捆绑。这个捆绑的应用程序可以保持运行,即使催化剂的父应用程序不是,这是大多数状态栏应用程序的工作方式,所以可以说这是一个更好的解决方案。我写了一个关于如何做到这一点的blog post,包括一个sample project。