肇鑫的技术博客

业精于勤,荒于嬉

macOS中菜单的处理,以及发送邮件

macOS中菜单的处理

基本原理

在macOS中,菜单项是通过NSResponder来进行传递的。根据的NSResponder文档

NSResponder is an abstract class that forms the basis of event and command processing in AppKit. The core classes—NSApplication, NSWindow, and NSView—inherit from NSResponder, as must any class that handles events.

也就是说,NSApplication, NSWindow, NSView都继承了NSResponder.实际使用中,还需要考虑它们的控制器,即NSWindowControllerNSViewController,以及NSApplication的代理NSApplicationDelegate。结论如下:

  1. 如果你需要同样名字的菜单在不同的情况下,有不同的结果。那么就在NSWindow, NSView或它们的控制器里实现。
  2. 如果你希望菜单的功能一致,就要在NSApplicationNSApplicationDelegate里实现。
  3. 菜单项被点击时,系统会在当前的first responder里进行查找action,找不到就到上一层responder里查找,直到找到或者全部responder查完为止。即顺序为当前视图->当前视图控制器->父视图->父视图控制器->…->当前窗口->当前窗口控制器->当前程序->当前程序代理

发送邮件

让用户通过邮件与开发者联系是常见的功能。代码如下:

//MARK: - Help Menu
extension NSApplication {
    @IBAction func contactDeveloper(_ sender: Any) {
        let mailAddress = "your email address"
        let mailBody = NSLocalizedString("Please use Chinese or English in your mail, if you can.", comment: "mail body")
        let service = NSSharingService(named: NSSharingServiceNameComposeEmail)!
        service.recipients = [mailAddress]
        service.perform(withItems: [mailBody])
    }
}

上面的代码放在AppDelegate.swift的最下面即可。打开故事板,假设你程序的菜单里Help菜单下,有一个叫“Contact Developer”的菜单项,鼠标右键点击这个菜单项,然后拖动它到First Responder,在弹出菜单中选contactDeveloper:就可以了。

menu_action