我有一个由核心数据实体填充的NSTableView
和添加项目/删除项目按钮都与接口生成器中的NSArrayController
和绑定连接。
撤销/重做菜单项可以撤销或重做添加/删除项的操作。
但是菜单项只被称为"撤销"。重做"。
我怎么能命名它们,如"撤消添加项","撤消删除项"等呢?
(我知道,以前有人问过类似的问题,但公认的答案要么是一个单一的,现在腐烂的链接,要么是子类NSManagedObject
的建议,并覆盖苹果文档中说的一个方法:"重要:你不能覆盖这个方法。")
在项目中添加NSArrayController的子类作为文件。在xib中,在数组控制器的标识检查器中,将类从NSArrayController
更改为您的新子类。
重写- newObject
方法
- (id)newObject
{
id newObj = [super newObject];
NSUndoManager *undoManager = [[[NSApp delegate] window] undoManager];
[undoManager setActionName:@"Add Item"];
return newObj;
}
还有- remove:sender
方法。
- (void)remove:(id)sender
{
[super remove:sender];
NSUndoManager *undoManager = [[[NSApp delegate] window] undoManager];
[undoManager setActionName:@"Remove Item"];
}
Register for NSManagedObjectContextObjectsDidChangeNotification:
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(mocDidChangeNotification:)
name:NSManagedObjectContextObjectsDidChangeNotification
object: nil];
并在相应的方法中解析userInfo字典:
- (void)mocDidChangeNotification:(NSNotification *)notification
{
NSManagedObjectContext* savedContext = [notification object];
// Ignore change notifications for anything but the mainQueue MOC
if (savedContext != self.managedObjectContext) {
return;
}
// Ignore updates -- lots of noise from maintaining user-irrelevant data
// Set actionName for insertion
for (NSManagedObject* insertedObject in
[notification.userInfo valueForKeyPath:NSInsertedObjectsKey])
{
NSString* objectClass = NSStringFromClass([insertedObject class]);
savedContext.undoManager.actionName = savedContext.undoManager.isUndoing ?
[NSString stringWithFormat:@"Delete %@", objectClass] :
[NSString stringWithFormat:@"Insert %@", objectClass];
}
// Set actionName for deletion
for (NSManagedObject* deletedObject in
[notification.userInfo valueForKeyPath:NSDeletedObjectsKey])
{
NSString* objectClass = NSStringFromClass([deletedObject class]);
savedContext.undoManager.actionName = savedContext.undoManager.isUndoing ?
[NSString stringWithFormat:@"Insert %@", objectClass] :
[NSString stringWithFormat:@"Delete %@", objectClass];
}
}
我已经在我自己的代码中测试过了——它很粗糙。可以花更多时间让actionName更漂亮。我删除了更新解析,因为:1)在多对象关系中插入和删除对象会生成其他对象的更新2)我不关心如何发现此时更改了哪些属性
我也有不方便用户使用的类名,所以这是为所有实体实现描述函数的好时机,并使用它而不是类名。
但这至少适用于项目中的所有对象控制器,并且很容易插入和删除。
[edit]更新了mikeD的建议,以覆盖重做具有反向名称。谢谢!