简体   繁体   中英

How to add subview in NSMenuItem WITHOUT storyboard?

I know there are answers like these , but almost everyone has their menu bar in storyboard. I made it purely in code without using.xib files so I'm not sure how to add a subview to my NSMenu item. My menu items show up like this:

func setupMenus() {
    // 1
    let menu = NSMenu()

    let one = NSMenuItem(title: "Toggle", action: #selector(didTapOne) , keyEquivalent: "1")
    menu.addItem(one)
    
    let warning = NSMenuItem(title: "INSTRUCTIONS", action: #selector(didTapWarning) , keyEquivalent: "")
    
    menu.addItem(warning)
    
    menu.addItem(NSMenuItem.separator())
    
    menu.addItem(NSMenuItem(title: "Quit", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q"))

}

which is defined in applicationDidFinishLaunching as follows:

    statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
    NSApp.hide(nil)
    if let button = statusItem.button {
        button.image = NSImage(systemSymbolName: "lock.shield", accessibilityDescription: "1")
    }

I'm not sure how I can add a subview to this. I just wish to add a line of text (that's greyed out: because they're instructions) and a custom button, both of which seem like they can be achieved by subview but I'm not sure how to implement that. Keep in mind I'm not utilizing a storyboard since I'm building a menu bar app.

The following swift code will create a submenu in your statusBarMenu and insert a composite view created by using an NSTextField and a functional NSButton. The code may be run in Xcode by creating a swift project and then deleting all the pre-supplied code in AppDelegate and copy/pasting the code below. AppDelegate.swift should be re-named to main.swift to avoid errors.

import Cocoa

class MenuHandler: NSObject {
 @objc func beep() {
  NSSound.beep()
 }
 @objc func info() {
  NSSound.beep()
}
}

 let app = NSApplication.shared

 let statusItem = NSStatusBar.system.statusItem(withLength:-1)
 statusItem.button!.title = "foobar"

 let menu = NSMenu()
 let menuHandler = MenuHandler()

 let one = NSMenuItem(title: "Toggle", action: #selector(menuHandler.beep) , keyEquivalent: "1")
 one.target = menuHandler
 menu.addItem(one)
   
 let warning = NSMenuItem(title: "INSTRUCTIONS", action: #selector(menuHandler.beep) , keyEquivalent: "")
 warning.target = menuHandler
 menu.addItem(warning)

 let subMenu = NSMenu()
 let info = NSMenuItem()
 let infoView = NSView(frame:NSMakeRect(0, 0, 180, 24 ))
 let txtFld = NSTextField(frame:NSMakeRect(10, 0, 130, 20 ))
 txtFld.backgroundColor = NSColor.clear
 txtFld.isEditable = false
 txtFld.isBordered = false
 txtFld.stringValue = "Bunch of information"
 let btn = NSButton(frame:NSMakeRect(140, 0, 24, 24 ))
 btn.image = NSImage(named:"myImage.png")
 btn.imageScaling = .scaleProportionallyDown
 btn.imagePosition = .imageOnly 
 btn.target = menuHandler
 btn.action = #selector(menuHandler.info)
 infoView.addSubview(txtFld)
 infoView.addSubview(btn)
 info.view = infoView
 subMenu.addItem(info)
 menu.setSubmenu(subMenu, for: warning)

 menu.addItem(NSMenuItem.separator())
 menu.addItem(NSMenuItem(title: "Quit", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q"))

 statusItem.menu = menu
 app.run()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM