如何命名撤消菜单项为核心数据通过绑定和NSArrayController添加/删除项目



我有一个由核心数据实体填充的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的建议,以覆盖重做具有反向名称。谢谢!

最新更新