macOS状态栏不显示图标的问题
在编写《macOS状态栏图标关键组件NSStatusItem》,发现状态栏的图标不见了。
import AppKit
import SwiftUI
class StatusBarController:ObservableObject {
private var statusItem: NSStatusItem!
init() {
// 创建系统菜单栏图标
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
if let button = statusItem.button {
button.image = NSImage(named: "templateIcon")
// button.toolTip = "轻压图片"
}
// 创建菜单
let menu = NSMenu()
let openItem = NSMenuItem(title: "打开 App", action: #selector(openApp), keyEquivalent: "o")
openItem.target = self
menu.addItem(openItem)
menu.addItem(NSMenuItem.separator())
let quitItem = NSMenuItem(title: "退出", action: #selector(NSApp.terminate(_:)), keyEquivalent: "q")
menu.addItem(quitItem)
statusItem.menu = menu
}
@objc func openApp() {
print("打开 App")
NSApp.activate(ignoringOtherApps: true)
}
}
问题并没有从代码层面检查出来。
排查流程
1、关闭应用,重新编译应用:图标未显示。
2、在访达中使用Command + Shift + G,打开快速访问:
~/Library/Developer/Xcode/DerivedData/
在DerivedData文件夹中,删除对应的mac应用。删除后,重新运行Xcode,发现图标仍然不显示。
3、检查图标:因为没有变更图标行的代码,因此没有重复检查。
4、AppDelegate没有持有 StatusBarController 的实例,它会在初始化后立即被释放,图标不会显示。
我在入口文件中,使用@StateObject创建StatusBarController实例。
@main
struct ImageSlimApp: App {
// @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@StateObject var statusBar = StatusBarController()
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
状态栏仍然无法显示图标。
5、App图标宽度未调整:在前面我曾经尝试修改NSStatusItem的宽度为100。
statusItem = NSStatusBar.system.statusItem(withLength: 100)
怀疑是,图标的NSStatusItem缓存的是100宽度,当我把状态栏的应用图标都退出后,仍然没有看到我的图标。
问题原因
回到《macOS菜单栏图标关键组件NSStatusItem》文章中,发现图标在使用isVisible方法之前,还是显示的。因此,怀疑isVisible方法导致的问题。
在初始化代码中,将isVisible方法设置为true:
init() {
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
if let button = statusItem.button {
button.image = NSImage(systemSymbolName: "star", accessibilityDescription: nil)
// 尝试设置 isVisible 为 true(以防之前设置过 false)
statusItem.isVisible = true
}
// ...
}
图标恢复正常。
总结
问题在于,当调用NSStatusItem.isVisible 一旦设为 false,它在某些情况下不会自动恢复。
这个属性会隐藏图标但不销毁它。但要注意:
必须显式再次设置为 true,否则图标不会自动回来。
重启后,只有完整清除了旧的 statusItem 实例并重新创建,才可能恢复显示。
注意:有些 macOS 版本上 isVisible = false 后系统可能不会重新布局菜单栏图标,造成看起来“永久消失”。
因为,在清理DerivedData文件夹的过程中,并没有同步重启Xcode,因为可能是Xcode存在缓存或者其他的缓存导致的这一问题。但还是没有想到,一个简单的配置不能通过重新打开应用以及清理DerivedData文件夹得到解决。
相关文章
macOS菜单栏图标关键组件NSStatusItem:https://fangjunyu.com/2025/06/26/macos%e8%8f%9c%e5%8d%95%e6%a0%8f%e5%9b%be%e6%a0%87%e5%85%b3%e9%94%ae%e7%bb%84%e4%bb%b6nsstatusitem/