难以实现NSUndoManager重做功能 [英] Difficulty implementing NSUndoManager redo function

查看:218
本文介绍了难以实现NSUndoManager重做功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的iOS应用程序中实现 NSUndoManager 。我有undo功能工作,但不是重做部分。我是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];
}
}

//当单击undo按钮时调用
- (void)undoDrawing
{
[undoManager撤消] ;
[undoManager registerUndoWithTarget:self
selector:@selector(resetImage)
object:pageView.canvas.image];
undoRedoStackIndex--;
}

//当重做按钮被点击时调用
- (void)redoDrawing
{
[undoManager redo];
undoRedoStackIndex ++;
}

- (void)resetImage
{
NSLog(@Hello); //此NSLog消息仅在我单击撤消时显示。
pageView.canvas.image = [oldImagesArrays objectAtIndex:undoRedoStackIndex];当我点击撤消或重做按钮 resetImage 时,会出现以下错误: 应该被调用,并将当前图像设置为我的图像堆栈中的下一个或上一个对象(当前值为undoRedoStackIndex),这只发生在我点击撤消,而不是重做。



解决方案&& ||

解决方案

您不需要跟踪更改,这是撤消

 这是一个可撤销的方法: {
if(_image!= image)
{
[[_undoManager prepareWithInvocationTarget:self] setImage:_image]; //这里我们让知道undo管理什么图像之前使用
[_image release];
_image = [image retain];

//发送通知以更新UI
}
}


$ b b

这是它。要撤销更改,只需调用 [_ undoManager undo] ,重做调用 [_ undoManager redo] 。当你告诉undo管理器撤销它会调用这个方法与旧的映像。如果您使用自定义按钮进行撤消操作,您可以使用 [NSUndoManager canUndo] 等验证。



没有限制撤销操作的数量。如果你需要在某些时候清除undo栈,只需调用 removeAllActions 方法。


I'm trying to implement an NSUndoManager in my iOS app. I got the undo functionality to work, but not the redo part. I'm quite new to iOS development and this is the first time that I've used NSUndoManager so it's probably something trivial.

My app is a painting/note taking app, I have a undo/redo stack with the last ten UIImages (I don't know if this is the most efficient way) in an array. When the user makes changes to the current image, the old image is pushed onto the stack, and the first image in the array is removed if the array already has ten objects. I have a int instance variable that I use to keep track of objects in the array and make sure that the correct image is displayed. My code looks like this:

- (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];
}

When I click the undo or redo buttons resetImage should get called, and set the current image to the next or previous object in my image stack (the current value of undoRedoStackIndex), this only happens when I click undo, but not redo.

Solutions && || better ways to do it would be appreciated.

解决方案

You do not need to keep track of the changes, this is what the undo manager is for.

Make an undoable method like this:

- (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
    }
}

This is it. To undo the change just call [_undoManager undo], to redo call [_undoManager redo]. When you tell the undo manager to undo it will call this method with the old image. If you use custom buttons for Undo operation you can validate it using [NSUndoManager canUndo], etc.

There is no limit for the number of undo operations. If you need to clean the undo stack at some point just call removeAllActions method.

这篇关于难以实现NSUndoManager重做功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆