У меня есть основное приложение данных с NSTableView, привязанным к NSArrayController. Я управляю добавлением и удалением объектов с помощью контроллера массива. Я пытаюсь добавить поддержку отмены / повтора, чтобы, когда человек удаляет объект из табличного представления, используя пункт меню, он мог отменить удаление.
Мой метод удаления:
- (IBAction)removeHost:(id)sender
{
NSInteger row = [bookmarkList selectedRow];
// Get the object so we can get to the attributes of the host
NSArray *a = [bookmarksController arrangedObjects];
NSManagedObject *object = [a objectAtIndex:row];
if (!object) return;
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSUndoManager *undoManager = [managedObjectContext undoManager];
if (managedObjectContext.undoManager == nil)
{
NSLog(@"No undo manager in app controller!");
} else {
NSLog(@"We've got an undo manager in app controller!");
}
[undoManager registerUndoWithTarget:self selector:@selector(addBookmarkObject:) object:object];
[bookmarksController removeObject:object];
[undoManager setActionName:@"Bookmark Delete"];
}
Удаление объекта работает нормально, но отмена - нет. Пункт меню Command-Z никогда не включается. Я настраиваю временный пункт меню и действие, чтобы проверить undoManager,
- (IBAction)stupidUndoRemoveHost:(id)sender
{
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSUndoManager *undoer = [managedObjectContext undoManager];
NSLog(@"canUndo? %hhd", [undoer canUndo]);
NSLog(@"canRedo? %hhd", [undoer canRedo]);
NSLog(@"isUndoRegistrationEnabled? %hhd", [undoer isUndoRegistrationEnabled]);
NSLog(@"undoMenuItemTitle = %@", [undoer undoMenuItemTitle]);
NSLog(@"redoMenuItemTitle = %@", [undoer redoMenuItemTitle]);
[undoer undo];
}
Используя этот IBAction, я могу отменить (ну, вроде как, он добавляет объект дважды, так что ясно, что здесь все еще не так), но я могу сделать это только один раз. Если я удаляю другой объект, canUndo возвращает 0, а stupidUndoRemoveHost ничего не делает.
Я знаю, что здесь что-то не понимаю. Я прочитал здесь больше постов, чем могу сосчитать, несколько постов в блоге и документацию Apple . Я делал это раньше, но это было как десять лет go, так что мои навыки немного ржавые. Любая помощь или указатели в правильном направлении с благодарностью.
Обновление: вот метод addBookmarkObject:
- (void)addBookmarkObject: (NSManagedObject *)object
{
[bookmarksController addObject:object];
}
А вот windowWillReturnUndoManager
из AppDelegate:
- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window {
// Returns the NSUndoManager for the application. In this case, the manager returned is that of the managed object context for the application.
NSUndoManager *undoManager = [[NSUndoManager alloc] init];
self.persistentContainer.viewContext.undoManager = undoManager;
if (self.persistentContainer.viewContext.undoManager == nil)
{
NSLog(@"No undo manager!");
} else {
NSLog(@"We've got an undo manager!");
}
return self.persistentContainer.viewContext.undoManager;
}