美文网首页macOS开发
macOS开发-NSMenu

macOS开发-NSMenu

作者: ForgetSou | 来源:发表于2020-10-30 09:32 被阅读0次

    macOS-NSMenu

    1 简述

    管理应用菜单的对象,通常会在程序的主菜单栏,视图右键菜单,Dock菜单使用。

    @interface NSMenu : NSObject <NSCopying, NSCoding, NSUserInterfaceItemIdentification, NSAccessibilityElement, NSAccessibility>
    

    2 NSMenu源码注解

    2.1 创建

    - (instancetype)initWithTitle:(NSString *)title NS_DESIGNATED_INITIALIZER;
    - (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
    

    2.2 常用属性

    // 菜单标题
    @property (copy) NSString *title;
    // 父菜单
    @property (nullable, assign) NSMenu *supermenu;
    // 当前菜单下的子菜单数组
    @property (copy) NSArray<NSMenuItem *> *itemArray;
    // item数量
    @property (readonly) NSInteger numberOfItems;
    // 是否自动启用项目
    @property BOOL autoenablesItems;
    // 菜单高度
    @property (readonly) CGFloat menuBarHeight;
    // 高亮的item
    @property (nullable, readonly, strong) NSMenuItem *highlightedItem API_AVAILABLE(macos(10.5));
    // 最小宽度
    @property CGFloat minimumWidth API_AVAILABLE(macos(10.6));
    @property (readonly) NSSize size API_AVAILABLE(macos(10.6));
    // 确定上下文菜单插件是否可以附加到菜单(如果用作上下文菜单)。
    @property (null_resettable, strong) NSFont *font API_AVAILABLE(macos(10.6));
    // 确定菜单是否包含状态图像的列
    @property BOOL showsStateColumn API_AVAILABLE(macos(10.5));
    

    2.3 常用函数

    // 菜单栏是否可见,visible = NO 隐藏
    + (void)setMenuBarVisible:(BOOL)visible;
    + (BOOL)menuBarVisible;
    
    // 添加和删除菜单项
    - (void)insertItem:(NSMenuItem *)newItem atIndex:(NSInteger)index;
    - (NSMenuItem *)insertItemWithTitle:(NSString *)string action:(nullable SEL)selector keyEquivalent:(NSString *)charCode atIndex:(NSInteger)index;
    - (void)addItem:(NSMenuItem *)newItem;
    - (NSMenuItem *)addItemWithTitle:(NSString *)string action:(nullable SEL)selector keyEquivalent:(NSString *)charCode;
    - (void)removeItemAtIndex:(NSInteger)index;
    - (void)removeItem:(NSMenuItem *)item;
    - (void)removeAllItems API_AVAILABLE(macos(10.6));
    - (void)itemChanged:(NSMenuItem *)item; // 在视觉上修改菜单项(例如,其标题更改)时调用。
    
    // 查找菜单项
    - (nullable NSMenuItem *)itemAtIndex:(NSInteger)index;
    - (nullable NSMenuItem *)itemWithTitle:(NSString *)title;
    - (nullable NSMenuItem *)itemWithTag:(NSInteger)tag;
    
    // 查找菜单项的索引
    - (NSInteger)indexOfItem:(NSMenuItem *)item;
    - (NSInteger)indexOfItemWithTitle:(NSString *)title;
    - (NSInteger)indexOfItemWithTag:(NSInteger)tag;
    - (NSInteger)indexOfItemWithRepresentedObject:(nullable id)object; // 返回具有给定表示对象的菜单中第一个菜单项的索引。
    - (NSInteger)indexOfItemWithSubmenu:(nullable NSMenu *)submenu; // 使用给定的子菜单返回菜单中菜单项的索引。
    - (NSInteger)indexOfItemWithTarget:(nullable id)target andAction:(nullable SEL)actionSelector; // 返回菜单中具有指定操作和目标的第一个菜单项的索引。
    

    3 NSMenuItem源码注解

    @interface NSMenuItem : NSObject <NSCopying, NSCoding, NSValidatedUserInterfaceItem, NSUserInterfaceItemIdentification, NSAccessibilityElement, NSAccessibility>
    
    // 初始化创建
    - (instancetype)initWithTitle:(NSString *)string action:(nullable SEL)selector keyEquivalent:(NSString *)charCode NS_DESIGNATED_INITIALIZER;
    - (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
    
    // 启动项
    @property (getter=isEnabled) BOOL enabled;
    
    // 隐藏状态
    @property (getter=isHidden) BOOL hidden API_AVAILABLE(macos(10.5)); // 菜单项是否隐藏
    @property (getter=isHiddenOrHasHiddenAncestor, readonly) BOOL hiddenOrHasHiddenAncestor API_AVAILABLE(macos(10.5)); 
    
    // Action & Target
    @property (nullable, weak) id target;
    @property (nullable) SEL action;
    
    // 标题
    @property (copy) NSString *title;
    @property (nullable, copy) NSAttributedString *attributedTitle;
    
    // 标签 
    @property NSInteger tag;
    
    // 状态
    @property NSControlStateValue state;
    static const NSControlStateValue NSControlStateValueMixed = -1;
    static const NSControlStateValue NSControlStateValueOff = 0;
    static const NSControlStateValue NSControlStateValueOn = 1;
    
    // 图片
    @property (nullable, strong) NSImage *image;
    @property (null_resettable, strong) NSImage *onStateImage; // checkmark by default
    @property (nullable, strong) NSImage *offStateImage; // none by default
    @property (null_resettable, strong) NSImage *mixedStateImage; // horizontal line by default
    
    // 子菜单
    @property (readonly) BOOL hasSubmenu;
    @property (nullable, strong) NSMenu *submenu;
    @property (nullable, readonly, assign) NSMenuItem *parentItem API_AVAILABLE(macos(10.6));
    
    // 按键
    @property (copy) NSString *keyEquivalent;
    @property NSEventModifierFlags keyEquivalentModifierMask;
    
    // 其它
    @property (readonly, copy) NSString *userKeyEquivalent;
    @property BOOL allowsKeyEquivalentWhenHidden API_AVAILABLE(macos(10.13)); 
    @property (nullable, copy) NSString *toolTip; 
    @property (getter=isHighlighted, readonly) BOOL highlighted API_AVAILABLE(macos(10.5)); // 是否应突出显示菜单项
    @property (nullable, strong) NSView *view API_AVAILABLE(macos(10.5)); // 菜单项的内容视图
    

    4 实际应用

    • Main Menu

      使用StoryBoard添加Menu比较方便添加和删除

      Main Menu
    • 右键Menu

      NSView上添加Menu

      - (void)viewDidLoad {
          [super viewDidLoad];
          NSMenu *menu = [[NSMenu alloc] initWithTitle:@"view menu"];
          NSMenuItem *item1 = [[NSMenuItem alloc] initWithTitle:@"item 1" action:@selector(menuClick) keyEquivalent:@""];
          item1.target = self;
          NSMenuItem *item2 = [[NSMenuItem alloc] initWithTitle:@"item 2" action:@selector(menuClick) keyEquivalent:@""];
          item2.target = self;
          
          [menu addItem:item1];
          [menu addItem:item2];
          
          // 添加二级菜单
          NSMenu *menu2 = [[NSMenu alloc] initWithTitle:@"sub menu"];
          NSMenuItem *itemA = [[NSMenuItem alloc] initWithTitle:@"itemA" action:@selector(menuClick) keyEquivalent:@""];
          itemA.target = self;
          NSMenuItem *itemB = [[NSMenuItem alloc] initWithTitle:@"itemB" action:@selector(menuClick) keyEquivalent:@""];
          itemB.target = self;
          [menu2 addItem:itemA];
          [menu2 addItem:itemB];
          // 二级菜单放在指定item上
          [menu setSubmenu:menu2 forItem:item2];
          self.view.menu = menu;
          
      }
      
      - (void)menuClick {
          
      }
      
    • Dock菜单

      在AppDelegate中重写applicationDockMenu方法

      - (NSMenu *)applicationDockMenu:(NSApplication *)sender {
          NSMenu *menu = [[NSMenu alloc] initWithTitle:@"dock menu"];
          NSMenuItem *item1 = [[NSMenuItem alloc] initWithTitle:@"item 1" action:@selector(menuClick) keyEquivalent:@""];
          item1.target = self;
          NSMenuItem *item2 = [[NSMenuItem alloc] initWithTitle:@"item 2" action:@selector(menuClick) keyEquivalent:@""];
          item2.target = self;
          
          [menu addItem:item1];
          [menu addItem:item2];
          
          // 添加二级菜单
          NSMenu *menu2 = [[NSMenu alloc] initWithTitle:@"sub menu"];
          NSMenuItem *itemA = [[NSMenuItem alloc] initWithTitle:@"itemA" action:@selector(menuClick) keyEquivalent:@""];
          itemA.target = self;
          NSMenuItem *itemB = [[NSMenuItem alloc] initWithTitle:@"itemB" action:@selector(menuClick) keyEquivalent:@""];
          itemB.target = self;
          [menu2 addItem:itemA];
          [menu2 addItem:itemB];
          // 二级菜单放在指定item上
          [menu setSubmenu:menu2 forItem:item2];
          
          return menu;
      }
      

    相关文章

      网友评论

        本文标题:macOS开发-NSMenu

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