美文网首页Swift进阶指南cocoaSwift&Objective-C
Swift动态定义NSMenu并添加响应事件

Swift动态定义NSMenu并添加响应事件

作者: 冷大大_hawkleng | 来源:发表于2016-08-24 10:55 被阅读726次

    近期在一个项目中需要根据一个数组动态生成相应的NSMenu及NSMenuItem,并通过单击某个NSButton弹出,现将该部分内容整理写个小Demo,以供大家参考。

    1. 首先在窗口中添加一个按钮,如下图所示:


      窗口中添加按钮
    2. 自定义一个类并添加一套测试数据,代码如下:
      class MyClass : NSObject {
      var id: Int = 0
      var name: String = ""

           override init() {
               super.init()
           }
       
           init(id: Int, name: String) {
               self.id = id
               self.name = name
           }
       }
      
       var myArray: Array<MyClass>!
      
       self.myArray = Array<MyClass>()
       self.myArray.append(MyClass(id: 1, name: "a"))
       self.myArray.append(MyClass(id: 2, name: "b"))
       self.myArray.append(MyClass(id: 3, name: "c"))
      
    3. 绑定按钮点击事件,并添加如下代码:
      @IBAction func btnCustomMenuClick(sender: AnyObject) {
      let topMenu = NSMenu.init(title: "Top")
      for myItem in self.myArray {
      let menuItem = NSMenuItem.init(title: myItem.name, action: Selector("menuItemClick:"), keyEquivalent: "")
      menuItem.representedObject = myItem
      topMenu.addItem(menuItem)
      }
      NSMenu.popUpContextMenu(topMenu, withEvent: NSApp.currentEvent!, forView: self.btnCustomMenu)
      }

    4. 定义菜单项点击事件,代码如下:
      @IBAction func menuItemClick(sender: AnyObject) {
      if let obj = sender.representedObject {
      if obj is MyClass {
      let myItem = obj as! MyClass
      NSLog("id: (myItem.id), name: (myItem.name)")
      }
      }
      }

    5. 编译运行并点击按钮将弹出菜单,如下图所示:


      点击弹出菜单
    6. 分别点击菜单项,调试窗口打印如下内容:


      点击菜单打印内容

    最后,附上该测试窗口完整代码如下:

    import Cocoa
    
    class CustomMenuTester: NSWindowController {
    
        @IBOutlet weak var btnCustomMenu: NSButton!
    
        class MyClass : NSObject {
            var id: Int = 0
            var name: String = ""
        
            override init() {
                super.init()
            }
        
            init(id: Int, name: String) {
                self.id = id
                self.name = name
            }
        }
    
        var myArray: Array<MyClass>!
    
        override var windowNibName: String {
            return "CustomMenuTester"
        }
    
        override func windowDidLoad() {
            super.windowDidLoad()
    
            // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
            self.myArray = Array<MyClass>()
            self.myArray.append(MyClass(id: 1, name: "a"))
            self.myArray.append(MyClass(id: 2, name: "b"))
            self.myArray.append(MyClass(id: 3, name: "c"))
        }
    
        @IBAction func btnCustomMenuClick(sender: AnyObject) {
            let topMenu = NSMenu.init(title: "Top")
            for myItem in self.myArray {
                let menuItem = NSMenuItem.init(title: myItem.name, action: Selector("menuItemClick:"), keyEquivalent: "")
                menuItem.representedObject = myItem
                topMenu.addItem(menuItem)
            }
            NSMenu.popUpContextMenu(topMenu, withEvent: NSApp.currentEvent!, forView: self.btnCustomMenu)
        }
    
        @IBAction func menuItemClick(sender: AnyObject) {
            if let obj = sender.representedObject {
                if obj is MyClass {
                    let myItem = obj as! MyClass
                    NSLog("id: \(myItem.id), name: \(myItem.name)")
                }
            }
        }
    
    }
    

    以上有问题或建议欢迎随时讨论,谢谢。

    相关文章

      网友评论

      • 大一号:keyEquivalent 这个参数是做什么用的啊
        大一号:@冷大大_hawkleng 好的谢谢~ 您有没有遇到这种情况: 无法获取点击item时的sender.
        冷大大_hawkleng:这个是swift的api文档里面有说明,如下:
        charCode
        A string representing a keyboard key to be used as the key equivalent. This value must not be nil (if there is no key equivalent, specify an empty NSString).

      本文标题:Swift动态定义NSMenu并添加响应事件

      本文链接:https://www.haomeiwen.com/subject/moknsttx.html