我正在尝试在我的iOS应用中实现NSUndoManager。我可以使用撤消功能,但不能执行重做部分。我是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的当前值)时,仅当我单击撤消而不发生重做时才会发生这种情况。

解决方案&& ||更好的方法将不胜感激。

最佳答案

您无需跟踪更改,这就是撤消管理器的用途。

制作如下这样的可撤消方法:

- (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方法。

关于objective-c - 难以实现NSUndoManager重做功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8249506/

10-09 02:52