UITextView实现撤销/重做功能(iOS/iPhone)

4
我有一个视图,其中UITextView始终具有焦点。我想做的是扩展内置的撤消/重做行为来支持撤消/重做,以便在我以编程方式设置文本时(例如,当我将其清除时,通过将其设置为@“”),也能够支持撤消/重做。
由于只有第一响应者可以获得撤消/重做事件,因此我认为我可以简单地使用UITextView的undoManager属性来创建我的调用。例如,
// 在清除文本之前... [[self.myTextView.undoManager prepareWithInvocationTarget:self] undoClear:self.myTextView.text]; [self.myTextView.undoManager setActionName:@"Clear"];
// ...
-(void)undoClear:(NSString *)textToRestore { self.myTextView.text = textToRestore; if ([self.myTextView.undoManager isUndoing]) { // 准备重做。 [[self.myTextView.undoManager prepareWithInvocationTarget:self] undoClear:@""]; } }
不幸的是,这并没有起作用。它:
1.引入了一个空项目到撤消堆栈中(“撤消”) 2.“撤消清除”在该项目之后添加(如果我点击“撤消”,我会看到“撤消清除”) 3.Undo Clear和Redo Clear工作,但是然后我再次看到“Undo Clear”,从那时起它就不起作用了。
有什么想法吗?我是否错了?
更新:似乎我已经找到了空撤消项的问题:当我在调用prepareWithInvocationTarget之后设置UITextView的文本时会发生这种情况。如果我在之前调用它,它就不会发生。有趣的是,如果我不调用prepareWithInvocationTarget(即通常情况下,当我设置UITextView的文本时),则不会将空项目推送到撤消堆栈中。
3个回答

3

好的,我想通了:

#1问题如我原帖更新中所述。

#2和#3问题只是我错误地使用了NSUndoManager。我的最终未清除方法(在撤销时调用)如下:

-(void)undoClear:(NSString *)textToRestore
{   
    NSString *textBackup = [self.myTextView.text copy];
self.myTextView.text = textToRestore;
if ([self.myTextView.undoManager isUndoing]) { // 准备重做。 [[self.myTextView.undoManager prepareWithInvocationTarget:self] undoClear:@""]; } else if ([self.myTextView.undoManager isRedoing]) { [[self.myTextView.undoManager prepareWithInvocationTarget:self] undoClear:textBackup]; }
[textBackup release]; }

现在它正在按照应有的方式工作。


你好,我觉得我的问题和这个类似,你能告诉我你是用什么方法调用了undoClear方法吗?谢谢。 - R. Dewi
@Risma:在设置textView内容之前。 - Anh
1
我遇到的一个问题是,当尝试实现这种方法时,所有之前的撤消操作都会被清除。因此,如果他们一直在输入内容,然后点击“清除”并想要撤消两次,它只会让他们回到之前的文本内容。 - philipkd
与上面只处理“清除”字段的方法不同,以下方法将使用字段的撤销/重做堆栈。只需为所有更改调用“[self changeTextValue:@”new value“]”:-(void)changeTextValue:(NSString *)newVal {   NSString * oldNotes = [self.txtViewNotes.text copy];      [self.txtViewNotes setText:newVal];      [[self.txtViewNotes.undoManager prepareWithInvocationTarget:self] changeTextValue:oldNotes]; } - strange

1
你可以将TextView更改为任何文本,并保留撤销和重做管理器的内存堆栈。self.content是UITextView。
-(void) yourClearAllButtonIsPressed
{
    [[self.content.undoManager prepareWithInvocationTarget:self] undoClear:self.content.text];
    [self.content setText:@""];//Or something else you want to change your textview to
}

}

//只有一个,我创建的方法

-(void) undoClearBlablabla:(NSString*) text
    {
        [[self.content.undoManager prepareWithInvocationTarget:self] undoClear:self.content.text];
        [self.content setText:text];
    }

你为什么要给这个-1?能解释一下吗?这对我来说是一个非常好的工作解决方案。 - coolcool1994
是的,请解释一下为什么有人会给这个点赞数-1,这看起来是正确的! - strange

0

我不确定你正在使用多少个文本字段,但是textBackup未被prepareWithInvocationTarget:保留。为什么它仍然在撤消堆栈中,几个清除之后?似乎在第一个之后可能仍然存在,但不会在第二个或自动释放池刷新后存在。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接