NSStatusItem 是 macOS 状态栏开发中的核心类,用于在系统顶部状态栏中显示自定义图标,并附加菜单或执行自定义操作。几乎所有显示在状态栏的第三方应用(如 Dropbox、iStat Menus、网易云音乐)都会用到它。
NSStatusItem 是什么?
NSStatusItem 表示状态栏上的一项,它是由系统的 NSStatusBar 创建的对象。不能直接实例化 NSStatusItem,必须通过 NSStatusBar 来创建。
let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
创建之后,可以:
1、显示图标(button.image)。
2、添加菜单(menu)。
3、响应点击事件(通过 button.action)。
当程序运行时执行这段NSStatusBar.system.statusItem代码,macOS就会立即在右上角状态栏中添加图标(即使没有使用AppDelegate)。
架构关系图
NSStatusItem示例代码:
private var statusItem: NSStatusItem!
// 创建系统菜单栏图标
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
if let button = statusItem.button {
button.image = NSImage(named: "templateIcon")
}
对应的架构关系图:
NSStatusBar(系统状态栏管理器)
└─ NSStatusItem(状态栏上的图标项)
└─ NSStatusBarButton(按钮 UI,可设置图标/点击事件)
NSStatusBar:macOS 中用于创建状态栏图标(系统右上角)的 API,很多 App(比如 Dropbox、网易云音乐、Clipy)都使用它来常驻状态栏,并提供快捷操作。
常用属性
1、button:NSStatusBarButton?,可用于设置图标、响应点击。
表示菜单栏上真正可见的图标按钮。
是一个 NSStatusBarButton 对象,继承自 NSButton。
可以对它设置图标、标题、点击事件:
if let button = statusItem.button {
button.image = NSImage(named: "templateIcon")
button.action = #selector(handleClick)
button.target = self
}
注意: 如果设置了 statusItem.menu,则 button.action 将不再生效(互斥)。
2、menu:NSMenu?,用于设置点击图标时显示的菜单。
设置菜单栏图标点击后显示的菜单。
指定一个 NSMenu 对象,当用户点击图标时弹出。
可以包含任意数量的 NSMenuItem,支持分隔符、子菜单等:
let menu = NSMenu()
menu.addItem(NSMenuItem(title: "打开 App", action: #selector(openApp), keyEquivalent: "o"))
menu.addItem(NSMenuItem.separator())
menu.addItem(NSMenuItem(title: "退出", action: #selector(NSApp.terminate(_:)), keyEquivalent: "q"))
statusItem.menu = menu
如果设置了 menu,则 button.action 不会被触发(因为点击就是弹出菜单)。
3、length:CGFloat,图标的宽度。
可以设置图标按钮的宽度,例如固定为 50:
let statusItem = NSStatusBar.system.statusItem(withLength: 50)
也可以设置100:

使用 NSStatusItem.variableLength(默认值)会根据图标大小自动适配。
4、statusBar:返回创建此项的 NSStatusBar 实例。
大部分场景都不会主动使用它,主要用于追踪归属。
let parentBar = statusItem.statusBar
5、isVisible:控制图标是否显示。
statusItem.isVisible = false // 隐藏图标
statusItem.isVisible = true // 重新显示
通常用于动态显示/隐藏图标,而不是完全销毁。
使用示例:
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")
}
// 创建菜单
let menu = NSMenu()
let hideItem = NSMenuItem(title: "隐藏 App", action: #selector(hideApp), keyEquivalent: "o")
hideItem.target = self
menu.addItem(hideItem)
statusItem.menu = menu
}
@objc func hideApp(_ sender: Any?) {
print("隐藏 App")
statusItem.isVisible = false
}
}
注意,isVisible = false在某些macOS版本上隐藏菜单后,可能重启或构建仍然无法恢复,因此只能在初始化中重新设置iSVisible = true,问题请见《macOS状态栏不显示图标的问题》。
6、autosaveName:给状态项命名以支持自动保存状态(如位置)。
在 macOS 支持菜单栏项目可拖拽排序时,这个字段用于标识每个图标项。
statusItem.autosaveName = NSStatusItem.AutosaveName("com.yourapp.menuitem")
如果设置了,它可以让系统记住上次用户拖动后的顺序。
7、NSStatusBar.system.removeStatusItem(item):移除图标项。
NSStatusBar.system.removeStatusItem(statusItem)
使用这个方法彻底移除菜单栏图标,不再显示。
调用后,原有的 statusItem 不能再使用,最好设为 nil。
注意事项
1、图标图像要使用模板图像(Template Image)
用于适配浅色/深色模式。
在 .xcassets 中设置 “Render As: Template Image”。

macOS状态栏图标推荐尺寸是 18×18 pt(对应 36×36 px @2x)。如果图片太大/太小/没有内边距,可能不会显示或显示异常。
图标配置的内容,详情请见《macOS状态栏图标(系统右上角)NSStatusBar》的设置状态栏图标部分。
2、menu 与 action 二选一
如果设置了 statusItem.menu,点击图标会弹出菜单,不会触发 button.action。
如果想响应点击而非弹出菜单,就不要设置 menu,而是设置 button.action。
// 创建系统菜单栏图标
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
if let button = statusItem.button {
button.image = NSImage(named: "templateIcon")
button.action = #selector(statusBarButtonClicked) // 1、想实现Button的 action 方法,就不能设置menu
button.target = self // 和 action 配合使用,不实现 Action 方法,就不用配置 target。
}
// 如果需要实现 Button 的 action 方法,下面的创建菜单部分就可以删除/隐藏
// 创建菜单
let menu = NSMenu()
let openItem = NSMenuItem(title: "打开 App", action: #selector(openApp), keyEquivalent: "o")
openItem.target = self
menu.addItem(openItem)
menu.addItem(NSMenuItem.separator())
statusItem.menu = menu // 2、单独设置menu,就不会触发button.action
总结
NSStatusItem作为NSStatusBar的重要组件,由系统的 NSStatusBar 创建的对象。不能直接实例化 NSStatusItem,必须通过 NSStatusBar 来创建。
相关文章
1、macOS状态栏图标(系统右上角)NSStatusBar:https://fangjunyu.com/2025/06/24/macos%e7%8a%b6%e6%80%81%e6%a0%8f%e5%9b%be%e6%a0%87%ef%bc%88%e7%b3%bb%e7%bb%9f%e5%8f%b3%e4%b8%8a%e8%a7%92%ef%bc%89nsstatusbar/
2、macOS单个菜单项类NSMenuItem:https://fangjunyu.com/2025/06/25/macos%e5%8d%95%e4%b8%aa%e8%8f%9c%e5%8d%95%e9%a1%b9%e7%b1%bbnsmenuitem/
3、macOS顶部和上下文菜单NSMenu:https://fangjunyu.com/2025/06/23/macos%e9%a1%b6%e9%83%a8%e5%92%8c%e4%b8%8a%e4%b8%8b%e6%96%87%e8%8f%9c%e5%8d%95nsmenu/
4、macOS状态栏不显示图标的问题:https://fangjunyu.com/2025/06/26/macos%e8%8f%9c%e5%8d%95%e6%a0%8f%e4%b8%8d%e6%98%be%e7%a4%ba%e5%9b%be%e6%a0%87%e7%9a%84%e9%97%ae%e9%a2%98/