Помощь с NSUndoManager

Хорошо, поэтому я хочу добавить возможность отмены определенных действий в моем приложении. Я собирался создать способ сделать это с помощью моих собственных протоколов или чего-то в этом роде, но потом я узнал о NSUndoManager. Я хотел бы использовать заложенный фундамент, но не могу понять. Мне нужно отменить несколько бросков кубиков, поэтому, если бы я мог сохранить предыдущие броски как объекты в NSArray, вероятно, было бы лучше всего. Я мог бы использовать NSMutableString, но предпочтительнее использовать массив.

Тогда я знаю, что вы можете встряхнуть, чтобы отменить, но я бы предпочел кнопку. Это доставляло мне больше всего хлопот. Я включил свои попытки ниже. Ни один из них не работал. Любая помощь будет оценена.

В viewDidLoad:

undoManager = [[NSUndoManager alloc] init];

Затем в методе, который бросает кости, я попробовал:

   [[undoManager prepareWithInvocationTarget:self] undoButton];
    [[undoManager prepareWithInvocationTarget:self] 
    [[undoManager prepareWithInvocationTarget:self] setString:[NSString stringWithFormat:@"%i", dice1num]];

setStrings:[NSArray arrayWithObjects:[NSString stringWithFormat:@"%i", dice1num]
    [NSString stringWithFormat:@"%i", dice1num],
    [NSString stringWithFormat:@"%i", dice1num],
    [NSString stringWithFormat:@"%i", dice1num],
    [NSString stringWithFormat:@"%i", dice1num], nil]];
[[undoManager prepareWithInvocationTarget:@selector()];
[undoManager setActionName:@"A roll"];

А вот IBAction, которое ссылается на кнопку отмены:

-(IBAction)undoButton{
           [undoManager undo];
}

заранее спасибо


person Andrew    schedule 03.04.2011    source источник
comment
Мой ответ на этот вопрос также может быть полезен здесь: Как отменить / redo в основном работает на iPhone OS?   -  person Brad Larson    schedule 04.04.2011
comment
Брэд, я просмотрел твой ответ, и он действительно хорош. Я бы хотел, чтобы это выглядело несколько дней назад. Я, наверное, уберу кое-что из этого. Спасибо за вашу помощь   -  person Andrew    schedule 04.04.2011
comment
Пример кода Apple DotViewUndo помог мне начать работу. Здесь пылится крошечный проект: developer.apple.com/library/mac/samplecode/DotViewUndo/   -  person original_username    schedule 09.04.2014


Ответы (1)


Я думаю, вы неправильно поняли функцию NSUndoManager. Менеджер отмены подобен стеку вызовов, необходимых для отмены того, что вы только что сделали. Итак, в принципе, ваша идея правильна - использовать объект коллекции в вашем случае NSArray для хранения нескольких шагов отмены. К сожалению, это работает немного иначе.

Как NSUndoManager работает

Менеджер отмены работает, сохраняя в памяти стек шагов отмены. Для каждого шага в вашем случае броска кости, который вы хотите отменить, вы регистрируете объект вызова, используя метод - (void)registerUndoWithTarget:self selector:@selector(setMyObjectTitle:) object:currentTitle. Вы делаете это при каждом броске кубиков. Регистрируйте только одну операцию за раз.

Для отмены вы вызываете метод отмены, как вы это делали, и тогда происходит то, что менеджер отмены вызывает операцию из стека отмены и выполняет ее.

Ваша главная ошибка заключалась в том, что вы пытались заново изобрести принцип работы менеджера отмены. Не регистрируйте массив, просто используйте один бросок кубика за раз.

Apple's отменить руководство по архитектуре

person GorillaPatch    schedule 03.04.2011
comment
Большое Вам спасибо. Мне пришлось немного поэкспериментировать и изменить концепцию в соответствии со своими потребностями, но я понял. Еще раз спасибо - person Andrew; 04.04.2011