我有一个需要在NSPopUpButton中显示的元素列表。我希望PopUp按钮按字母顺序排序显示列表。此外,列表中有一个新的MenuItem,它将从文本字段中拾取一个字符串并将其插入到PopUp按钮中。所以,我想问两个问题:
答案 0 :(得分:2)
如果您使用NSArrayController
填充弹出按钮(或更确切地说,它的菜单),那么您只需定义一个排序描述符来处理排序。
让阵列控制器第一次使用弹出按钮可能有点棘手,但如果将弹出按钮的内容绑定到阵列控制器的arrangedObjects
然后绑定内容值到模型对象的合适字符串属性,你应该没问题。
然后,添加一个新项只需要通过数组控制器添加一个项目。
因此,如果您不熟悉NSArrayController
类和绑定,以下是如何在Interface Builder中执行此操作的简短说明。假设您的元素具有名为name
的字符串属性。
arrangedObjects
控制器键。这是该绑定的默认选项。arrangedObjects
控制器密钥和name
模型密钥路径。这将在菜单中显示正确的文字。setSortDescriptors:
方法)。为此,您可能希望在文件所有者上定义一个插座来保存阵列控制器。add:
方法。这应该可以让你使用最少的代码,以及一点点Interface Builder魔法。
对于相当简单的UI元素,绑定可以真正节省大量工作。关于他们的更多信息here。
编辑添加示例:
有关如何执行此操作的示例,请考虑具有应用程序委托的应用程序,该应用程序委托具有data
属性,一个字典数组,具有name
属性。请注意,这是一个比您的示例更深的抽象级别,其中数组只包含单个字符串。就个人而言,我更喜欢这样。
self.data = [NSMutableArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:@"Flowers", @"name", nil],
[NSDictionary dictionaryWithObjectsAndKeys:@"Animals", @"name", nil],
[NSDictionary dictionaryWithObjectsAndKeys:@"Trees", @"name", nil],
nil];
// Sort the array controller alphabetically by the name property
NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
self.arrayController.sortDescriptors = [NSArray arrayWithObject:sd];
答案 1 :(得分:1)
我设法使用以下绑定对弹出按钮进行排序:
[arrayController bind:@"contentArray" toObject:self withKeyPath:@"displayElements" options:nil];
[popUpButton bind:@"content" toObject:arrayController withKeyPath:@"arrangedObjects" options:nil];
[popUpButton bind:@"contentValues" toObject:arrayController withKeyPath:@"arrangedObjects.title" options:nil];
我也改变了init中的语句:
displayElements = [[NSMutableArray alloc] initWithObjects:@"one",@"two",@"three", nil];
到
displayElements = [[NSMutableArray alloc] initWithObjects:[[NSMenuItem alloc]initWithTitle:@"one" action:nil keyEquivalent:@""],
[[NSMenuItem alloc]initWithTitle:@"two" action:nil keyEquivalent:@""],
[[NSMenuItem alloc]initWithTitle:@"three" action:nil keyEquivalent:@""],
nil];
并且排序工作正常。
现在的问题是,如果我在任何菜单项中添加子菜单,之后我将新的NSMenuItem添加到阵列控制器,之前添加的子菜单消失,如下图所示:
在添加新项目之前:
添加新商品后:
我们对元素进行排序时会显示相同的行为
关于解决这个问题的任何想法??
答案 2 :(得分:0)
感谢@Monolo的回答
我已经能够在NSArrayController的弹出窗口中加载值(已存储在NSMutableArray中)。但我仍然坚持排序的事情。下面是代码,我无法弄清楚它有什么问题 的 ControllerClass.h 强>
@interface ControllerClass : NSObject{
NSWindow *window;
NSArray *sortDescriptorArray;
NSMutableArray *displayElements;
NSSortDescriptor *sortDescriptor;
IBOutlet NSArrayController *arrayController;
IBOutlet NSTextField *newItemTextField;
}
@property (readwrite,retain) NSMutableArray *displayElements;
-(id)init;
-(IBAction)AddItem:(id)sender;
@end
=============================================== =============
的 ControllerClass.m 强>
#import "ControllerClass.h"
@implementation ControllerClass
@synthesize displayElements;
-(id)init
{
self =[super init];
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"displayElements" ascending:YES];
sortDescriptorArray = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[arrayController setSortDescriptors:sortDescriptorArray];
displayElements = [[NSMutableArray alloc] initWithObjects:@"one",@"two",@"three", nil];
return self;
}
-(IBAction)AddItem:(id)sender
{
[arrayController addObject:[newItemTextField stringValue]];
}
@end