macOS开发-NSMenu
2020-10-30 本文已影响0人
ForgetSou
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
使用
Main MenuStoryBoard
添加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; }