Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 难以实现NSUndoManager重做功能_Objective C_Ios_Cocoa Touch_Nsundomanager - Fatal编程技术网

Objective c 难以实现NSUndoManager重做功能

Objective c 难以实现NSUndoManager重做功能,objective-c,ios,cocoa-touch,nsundomanager,Objective C,Ios,Cocoa Touch,Nsundomanager,我正在尝试在我的iOS应用程序中实现一个NSUndoManager。我得到了撤销功能,但没有重做部分。我对iOS开发非常陌生,这是我第一次使用NSUndoManager,所以这可能是一件微不足道的事情 我的应用程序是一个绘画/笔记应用程序,我有一个撤销/重做堆栈,其中包含最后十个UIImages(我不知道这是否是最有效的方法)。当用户对当前图像进行更改时,旧图像将被推送到堆栈上,如果阵列已经有十个对象,则移除阵列中的第一个图像。我有一个int实例变量,用于跟踪数组中的对象并确保显示正确的图像。我

我正在尝试在我的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];
}
当我单击“撤消”或“重做”按钮时,应调用“重置图像”,并将当前图像设置为图像堆栈中的下一个或上一个对象(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
    }
}
就是这样。要撤消更改,只需调用
[\u undoManager undo]
,再调用
[\u undoManager redo]
。当您告诉撤消管理器撤消时,它将使用旧图像调用此方法。如果使用自定义按钮执行撤消操作,则可以使用
[NSUndoManager canUndo]
等进行验证


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

@JoshCaswell我已经对我的问题做了一些澄清。谢谢你,让它起作用了。我怀疑这比我做的容易。谢谢Anders@Davyd您好,您能帮我解决这个问题吗:)“发布更新UI的通知”如何更新UIImage?应该在数据模型中使用像我发布的那样带有撤消管理器的方法。这就是为什么我对提出通知发表评论。例如:[[NSNotificationCentre defaultCentre]postNotification:XXMyDataModelDidChangeImageNotification对象:self]。这意味着应该有一个视图控制器,其中的视图(UIImageView)实际显示图像。此视图控制器应订阅来自数据模型的通知,并在收到通知时更新视图。或者,可以使用KVO。我希望这有帮助。