【问题标题】:NSSharingService Sharing SubmenuNSSharingService 共享子菜单
【发布时间】:2012-09-04 21:47:22
【问题描述】:

如何在 Mac 应用程序中添加共享子菜单?例如 Safari > 文件 > 共享。我戳了Apple SharingServices sample code,但它不包括工作菜单项。

现在我有一个按钮,点击时会显示可用共享服务的选择器:

NSMutableArray *shareItems = [NSMutableArray arrayWithObject:[self.noteSynopsisView string]];
NSSharingServicePicker *sharingServicePicker = [[NSSharingServicePicker alloc] initWithItems:shareItems];
sharingServicePicker.delegate = self;
[sharingServicePicker showRelativeToRect:[self.shareButton bounds] ofView:self.shareButton preferredEdge:NSMaxYEdge];

我还在我的 MainWindow.xib 的文件菜单下定义了一个共享子菜单项。

据我了解,NSSharingService 列表是即时生成的。所以我无法真正为我在 Interface Builder 中创建的菜单项预定义服务。

感谢您的帮助。

【问题讨论】:

    标签: macos cocoa menu menuitem submenu


    【解决方案1】:

    看看 NSSharingService 的 +sharingServicesForItems:。在 -validateMenuItem: 方法中,您可以使用它返回的 NSSharingServices 的 -title 和 -image 创建子菜单。将每个服务与每个菜单项相关联,并将每个菜单项的操作指向此:

    - (IBAction)shareFromService:(id)sender {
      [[sender representedObject] performWithItems: arrayOfItemsToShare];
    }
    

    这真的很简单。苹果在这方面做得很好。

    【讨论】:

    • +1 我也非常感谢!我能够在 NSMenu 对象的 willOpen: 委托方法中实现这一点。
    • 而不是 validateMenuItem,它可能应该在 menuNeedsUpdate: 委托中完成。感谢您的指导。
    • 我还注意到这不包括“更多”条目,而不是 NSSharingServicePicker 显示的最近条目。
    【解决方案2】:

    我发现要点可以帮助您轻松创建适当服务的子菜单。 https://gist.github.com/eternalstorms/4132533

    这是一个 NSSharingServicePicker 类别。

    【讨论】:

      【解决方案3】:

      Swift 版本:

      extension NSSharingServicePicker {
          
          class func menu(forSharingItems items: [AnyHashable]) -> NSMenu? {
              
              let sharingServices = NSSharingService.sharingServices(forItems: items)
              
              if sharingServices.isEmpty {
                  return nil
              }
              
              let menu = NSMenu()
              
              for service in sharingServices {
                  
                  let item = MenuItem(label: service.title, action: #selector(_openSharingService), target: self, userInfo: ["sharingItems": items])
                  
                  item.image = service.image
                  item.representedObject = service
                  item.target = self
                  menu.addItem(item)
                  
              }
              
              return menu
              
          }
          
          @objc class private func _openSharingService(sender: MenuItem) {
              
              guard let items = sender.userInfo["sharingItems"] as? [AnyHashable], let service = sender.representedObject as? NSSharingService else {
                  return
              }
              
              service.perform(withItems: items)
              
          }
          
      }
      
      class MenuItem: NSMenuItem {
          
          var userInfo: [String : Any] = [:]
          
          init(label: String, action: Selector?, target: AnyObject?, userInfo: [String : Any]) {
              self.userInfo = userInfo
              super.init(title: label, action: action, keyEquivalent: "")
          }
          
          required init(coder decoder: NSCoder) {
              super.init(coder: decoder)
          }
          
      }
      

      【讨论】:

        猜你喜欢
        • 2019-03-13
        • 1970-01-01
        • 1970-01-01
        • 2011-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-13
        相关资源
        最近更新 更多