Сложность в реализации функции возврата NSUndoManager - PullRequest
6 голосов
/ 24 ноября 2011

Я пытаюсь реализовать NSUndoManager в своем приложении для iOS.Я получил функциональность отмены, чтобы работать, но не часть повторения.Я довольно новичок в разработке для iOS, и я впервые использую NSUndoManager, так что это, вероятно, что-то тривиальное.

Мое приложение - приложение для рисования / создания заметок, у меня есть стек отмены / повторного выполнения с последними десятью UIImage с (я не знаю, является ли это наиболее эффективным способом) в массиве.Когда пользователь вносит изменения в текущее изображение, старое изображение помещается в стек, и первое изображение в массиве удаляется, если в массиве уже есть десять объектов.У меня есть int переменная экземпляра, которую я использую, чтобы отслеживать объекты в массиве и убедиться, что отображается правильное изображение.Мой код выглядит следующим образом:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    if (oldImagesArrays.count >= 10) {
        [oldImagesArrays removeObjectAtIndex:0];
    }
    UIImage * currentImage = pageView.canvas.image;
    if (currentImage != nil) {
        [oldImagesArrays addObject:currentImage];
        undoRedoStackIndex = oldImagesArrays.count -1;
    }
    [...]
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    UIImage * currentImage = [oldImagesArrays lastObject];
    if (currentImage != pageView.canvas.image) {
        [undoManager registerUndoWithTarget:self selector:@selector(resetImage)  
        object:currentImage];
    }
}

// Gets called when the undo button is clicked
- (void)undoDrawing
{
    [undoManager undo];
    [undoManager registerUndoWithTarget:self 
                           selector:@selector(resetImage)
                             object:pageView.canvas.image];
    undoRedoStackIndex--;
}

// Gets called when the redo button is clicked
- (void)redoDrawing
{
    [undoManager redo];
    undoRedoStackIndex++;
}

- (void)resetImage
{
    NSLog(@"Hello"); // This NSLog message only appears when I click undo.
    pageView.canvas.image = [oldImagesArrays objectAtIndex:undoRedoStackIndex];
}

Когда я нажимаю кнопки отмены или повтора resetImage должен быть вызван, и установить текущее изображение на следующий или предыдущий объект в моем стеке изображений (текущее значение undoRedoStackIndex), это происходит только тогда, когда я нажимаю отмену, но не повтор.

Решения && ||Буду признателен за лучшие способы сделать это.

1 Ответ

6 голосов
/ 24 ноября 2011

Вам не нужно отслеживать изменения, для этого предназначен менеджер отмены.

Создайте такой способ отмены:

- (void)setImage:(UIImage*)image
{
    if (_image != image)
    {
        [[_undoManager prepareWithInvocationTarget:self] setImage:_image]; // Here we let know the undo managed what image was used before
        [_image release];
        _image = [image retain];

        // post notifications to update UI
    }
}

Вот и все.Чтобы отменить изменение, просто позвоните [_undoManager undo], чтобы повторить вызов [_undoManager redo].Когда вы говорите менеджеру отмены отмены, он вызывает этот метод со старым образом.Если вы используете пользовательские кнопки для операции отмены, вы можете проверить ее, используя [NSUndoManager canUndo] и т. Д.

Количество операций отмены не ограничено.Если вам нужно очистить стек отмены в какой-то момент, просто вызовите метод removeAllActions.

...