MacOS开发系列5-创建StatusBarApp(无窗体、不在Dock显示,只在状态显示)

2,807 阅读2分钟

在Mac上使用了也很久了,不知道你们有没有对那些无窗体,不在Dock显示,并且只在StatusBar显示的App充满了兴趣。

如苹果自带的那些蓝牙、Wifi他们其实是一个APP,还有应用市场上的某些APP(具体的就不提名字,怕有推广嫌疑),都是可以实现不在Dock显示、无窗体。甚至有的在点击StatusBar弹出的菜单还是可以自定义的视图。

那么今天小弟我,就在这里一步步引导大家如何创建此类APP

demo代码已经上传到GitHub传送门

创建APP

打开Xcode,这里我们选择语言为Swift,interface为Storyboard的MacOSApp:

设置不在Dock 显示

打开项目里面的plist文件,添加属性Application is agent (UIElement)并且设置为YES.同理如果之后想显示在Dock,只需要设置为NO即可:

编辑Menu,把不需要的菜单栏通通都干掉

打开Storyboard,选中Menu,然后把多余的菜单都删掉。只剩下StatusBarAppExample这一项:

不显示Window

再次打开Storyboard,把项目里的Window Controller Scene删除:

这样我们基本就实现一个App不显示在Dock上,同时还没有任何一个Window。

但在运行后,发现程序是正常运行的,可是StatusBar并不显示我们的App。不要慌!请继续往下看

为StatusBar添加icon

  1. 首先要准备两张不同size的icon的图片,分别为1x2x的,大小分别是18x1836*36.然后拖动到Assert里面去即可:

  1. 设置MenuIBOutletAppDelegate文件里面.这个就算在Storyboard中右键点击menu,然后拖动到AppDelegate中即可自动生成。(如果这个都不懂,建议你去看看Objectivec从入门到放弃这本书)

  1. 然后在AppDelegate声明一个NSStatusItem对象:如下:
var statusItem: NSStatusItem?
  1. 重写AppDelegate中的awakeFromNib这个函数。
override func awakeFromNib() {
  super.awakeFromNib()

  statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
  statusItem?.button?.title = "WindowSnap"
        
  let itemImage = NSImage(named: "SplitScreen")
  itemImage?.isTemplate = true
  statusItem?.button?.image = itemImage
  if let menu = menu {
     statusItem?.menu = menu
   }
}

完整AppDelegate如下:

这个时候再运行程序,就会看到StatusBar上有我们的App了:

这样就基本完成了一个无window,不在Dock显示,并且只在StatusBar上显示的App。

等等,不是说可以自定义视图吗?就好像淘宝Mac版的旺旺一样吗?不要急!可以阅读我下一篇文章【MacOS开发系列6-自定义菜单栏NSMenu和NSMenuItem】