You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让NSStatusItem占满macOS菜单栏的全部高度?

macOS菜单栏项目占满全高度实现问题

我想在macOS菜单栏里添加一个能占满菜单栏全部高度的项目,效果可以参考FaceTime的UI:

FaceTime菜单栏UI示例

但我自己实现的时候,只能让项目距离菜单栏上下边缘各留1pt的空隙:

当前实现效果示例

注:带刘海的菜单栏中,就算是FaceTime也没法延伸到边缘,但它还是比我的实现版本在顶部和底部多延伸了1pt。

我已经试过用NSStatusItem的button、已弃用的view,还有SwiftUI的MenuBarExtra来实现,但都没达到预期效果。

以下是生成上面第二张截图的示例代码:

final class StatusItemManager: ObservableObject {
    var statusButtonItem: NSStatusItem?
    var statusViewItem: NSStatusItem?
    
    /// 注意这里用了已废弃的API——如果可以的话我不想用这些
    func showViewStatusItem() {
        statusViewItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
        
        guard let statusViewItem else { return }
        
        let iconView = NSHostingView(rootView: ItemView(title: "View"))
                
        statusViewItem.view = iconView
        
        statusViewItem.view?.frame = NSRect(x: 0, y: 0, width: 50, height: 40)
    }
    
    /// 非废弃API,但还是不行
    func showButtonStatusItem() {
        statusButtonItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
        
        guard let statusButtonItem else { return }
        
        let iconView = NSHostingView(rootView: ItemView(title: "Button"))
        
        iconView.frame = NSRect(x: 0, y: 0, width: 50, height: 24)

        statusButtonItem.button?.addSubview(iconView)

        statusButtonItem.button?.action = #selector(menuBarButtonPressed)
        statusButtonItem.button?.target = self

        statusButtonItem.button?.frame = iconView.frame
    }
    
    struct ItemView: View {
        var title: String
        
        var body: some View {
            Text(title)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .background(Color.green)
        }
        
    }
    
    @objc func menuBarButtonPressed(_ sender: Any?) {
        print("pressed")
    }
}

struct ContentView: View {
    @StateObject var manager = StatusItemManager()
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, world!")
        }
        .padding()
        .onAppear {
            manager.showButtonStatusItem()
            manager.showViewStatusItem()
        }
    }
}

内容的提问来源于stack exchange,提问作者jnpdx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:47:12