难以实现NSUndoManager重做功能



我正试图在我的iOS应用程序中实现NSUndoManager。我得到了撤消功能的工作,但不是重做部分。我对iOS开发很陌生,这是我第一次使用NSUndoManager,所以它可能是微不足道的。

我的应用程序是一个绘画/笔记应用程序,我有一个撤消/重做堆栈与最后十个UIImage s(我不知道这是否是最有效的方式)在一个数组。当用户对当前图像进行更改时,旧图像被压入堆栈,如果数组中已经有十个对象,则数组中的第一个图像将被删除。我有一个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]等验证它。

undo操作的次数没有限制。如果您需要在某个时候清除撤消堆栈,只需调用removeAllActions方法。

相关内容

  • 没有找到相关文章

最新更新