ATV*_*ATV 10 cocoa objective-c appkit cocoa-bindings nspopupbutton
a的内容NSPopupButton
绑定到一个NSArray
字符串.
我们如何通过绑定插入分隔项?
" -
"字符串(如旧版/经典日)不起作用,即字面上显示为" -
"菜单项.
有没有标准的Cocoa类和绑定的开箱即用的解决方案?
这应该是一个很重要的问题,但我找不到任何解决办法,不涉及傻黑客就像子类的问题NSMenu
,NSPopupButton
或者其他非直观的变通.
在使用绑定时,我找不到一种干净的方法来动态地将分隔符添加到菜单中.我发现的最简单(也是最可重用)的方法是使用NSMenuDelegate动态地将NSMenuItems替换为特定标题,例如委托方法@"---"
中的分隔符项menuNeedsUpdate:
.
步骤1:创建符合NSMenuDelegate协议的NSObject
#import <Cocoa/Cocoa.h>
@interface SeparatorMenuDelegate : NSObject <NSMenuDelegate>
@end
@implementation SeparatorMenuDelegate
-(void)menuNeedsUpdate:(NSMenu *)menu {
NSArray* fakeSeparators = [[menu itemArray] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"title == '---'"]];
for (NSMenuItem* fakeSep in fakeSeparators) {
[menu insertItem:[NSMenuItem separatorItem] atIndex:[menu indexOfItem:fakeSep]];
[menu removeItem:fakeSep];
}
}
@end
Run Code Online (Sandbox Code Playgroud)
第2步:在Interface Builder中链接.
将Object拖出到包含NSPopupButton实例的场景中.
将对象的类设置为 SeparatorMenuDelegate
旋转打开文档大纲中的NSPopupButton控件,然后选择其中的菜单.然后将菜单的委托设置为SeparatorMenuDelegate
您之前拖动的对象.
在此之后,菜单中标题为""---"的所有项目都将转换为分隔项目.
如果在同一场景中有多个NSPopupButton实例,则可以将其Menu的委托设置为同一对象(SeparatorMenuDelegate
每个场景只需要一个).
小智 5
恕我直言,最干净的解决方案仍然是子类化NSMenu - 这种自定义正是子类化的目的。以下解决方案基于@matt 多年前在Cocoabuilder上写的内容,并更新为更普遍适用,包括在 High Sierra 上。
首先,定义一个“魔法字符串”来表示代码中的分隔符项;在所有受影响的类将导入的头文件中执行此操作。在这个例子中,我选择了“---”,当然,这可以是你喜欢的任何字符串:
#define MY_MENU_SEPARATOR @"---"
Run Code Online (Sandbox Code Playgroud)
其次,继承 NSMenu并覆盖添加菜单项的两个方法,以处理特殊分隔符情况:
@implementation MyMenu
- (NSMenuItem*)addItemWithTitle:(NSString*)aString action:(SEL)aSelector keyEquivalent:(NSString*)keyEquiv
{
if ([aString isEqualToString:MY_MENU_SEPARATOR])
{
NSMenuItem *separator = [NSMenuItem separatorItem];
[self addItem:separator];
return separator;
}
return [super addItemWithTitle:aString action:aSelector keyEquivalent:keyEquiv];
}
- (NSMenuItem*)insertItemWithTitle:(NSString*)aString action:(SEL)aSelector keyEquivalent:(NSString*)keyEquiv atIndex:(NSInteger)index
{
if ([aString isEqualToString:MY_MENU_SEPARATOR])
{
NSMenuItem *separator = [NSMenuItem separatorItem];
[self insertItem:separator atIndex:index];
return separator;
}
return [super insertItemWithTitle:aString action:aSelector keyEquivalent:keyEquiv atIndex:index];
}
@end
Run Code Online (Sandbox Code Playgroud)
就是这样。在Interface Builder的Identity检查器中将受影响的菜单设置为MyMenu类,它们将在需要的地方插入分隔项。适用于菜单栏菜单以及弹出窗口。
归档时间: |
|
查看次数: |
2757 次 |
最近记录: |