问题描述
正如您从图片中看到的,我有 menu bar popover
,即 transparent
,我希望它改为特定颜色。
我该怎么办,你能帮我一把吗?
状态栏控制器
import AppKit
import SwiftUI
class StatusBarController {
@Observedobject var userPreferences = UserPreferences.instance
private var statusBar: NsstatusBar
var statusItem: NsstatusItem
private var popover: NSPopover
init(_ popover: NSPopover) {
self.popover = popover
statusBar = NsstatusBar.init()
statusItem = NsstatusBar.system.statusItem(withLength: NsstatusItem.variableLength)
if let statusBarButton = statusItem.button {
statusBarButton.image = #imageLiteral(resourceName: "Fork")
statusBarButton.image?.size = NSSize(width: 18.0,height: 18.0)
statusBarButton.image?.istemplate = true
statusBarButton.action = #selector(togglePopover(sender:))
statusBarButton.target = self
statusBarButton.imagePosition = NSControl.ImagePosition.imageLeft
}
}
@objc func togglePopover(sender: AnyObject) {
if(popover.isShown) {
hidePopover(sender)
}else {
showPopover(sender)
}
}
func showPopover(_ sender: AnyObject) {
if let statusBarButton = statusItem.button {
popover.show(relativeto: statusBarButton.bounds,of: statusBarButton,preferredEdge: NSRectEdge.maxY)
}
}
func hidePopover(_ sender: AnyObject) {
popover.performClose(sender)
}
}
应用委托
import Cocoa
import SwiftUI
@main
class AppDelegate: NSObject,NSApplicationDelegate {
var statusBar: StatusBarController?
var popover = NSPopover.init()
var timer: Timer? = nil
func applicationDidFinishLaunching(_ aNotification: Notification) {
let contentView = ContentView()
popover.contentSize = NSSize(width: 360,height: 360)
popover.contentViewController = NSHostingController(rootView: contentView)
statusBar = StatusBarController.init(popover)
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
}
解决方法
参考:https://www.programmersought.com/article/29256315686/
结果:
使用此扩展:
extension NSPopover {
private struct Keys {
static var backgroundViewKey = "backgroundKey"
}
private var backgroundView: NSView {
let bgView = objc_getAssociatedObject(self,&Keys.backgroundViewKey) as? NSView
if let view = bgView {
return view
}
let view = NSView()
objc_setAssociatedObject(self,&Keys.backgroundViewKey,view,.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
NotificationCenter.default.addObserver(self,selector: #selector(popoverWillOpen(_:)),name: NSPopover.willShowNotification,object: nil)
return view
}
@objc private func popoverWillOpen(_ notification: Notification) {
if backgroundView.superview == nil {
if let contentView = contentViewController?.view,let frameView = contentView.superview {
frameView.wantsLayer = true
backgroundView.frame = NSInsetRect(frameView.frame,1,1)
backgroundView.autoresizingMask = [.width,.height]
frameView.addSubview(backgroundView,positioned: .below,relativeTo: contentView)
}
}
}
var backgroundColor: NSColor? {
get {
if let bgColor = backgroundView.layer?.backgroundColor {
return NSColor(cgColor: bgColor)
}
return nil
}
set {
backgroundView.wantsLayer = true
backgroundView.layer?.backgroundColor = newValue?.cgColor
}
}
}
用法:
self.popover = popover
self.popover.backgroundColor = #colorLiteral(red: 0.3411764801,green: 0.6235294342,blue: 0.1686274558,alpha: 1)