使用UITextView(iOS / iPHone)撤消/重做

时间:2010-11-01 15:25:41

标签: iphone uitextview undo nsundomanager redo

我有一个视图,其中UITextView始终具有焦点。我想要做的是扩展内置的撤消/重做行为,以便在我以编程方式设置文本时支持撤消/重做(例如,当我清除它时,通过将其设置为@“”)。

由于只有firstResponder获取了undo / redo事件,我以为我只是使用UITextView的undoManager属性来创建我的调用。例如,

// Before clearing the text...
[[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])
    {
      // Prepare the redo.
      [[self.myTextView.undoManager prepareWithInvocationTarget:self] undoClear:@""];  
    }
}

不幸的是,这不起作用。它:

  1. 将空项目引入撤消堆栈(“撤消”)
  2. 在该项目之后添加“撤消清除”(如果我点击“撤消”,我看到“撤消清除”)
  3. 撤消清除和重做清除工作,然后我再次看到“撤消清除”,它从那里起作用不起作用。
  4. 有什么想法吗?我接近这个错误吗?

    更新:好像我已经找到了空的撤销项问题:当我在调用prepareWithInvocationTarget 后设置UITextView 的文本时会发生这种情况。如果我之前打电话,它就不会发生。有趣的是,如果我不调用prepareWithInvocationTarget(即,通常,当我设置UITextView的文本时),空项不会被推到撤消堆栈上。

3 个答案:

答案 0 :(得分:3)

好的,明白了:

#1的问题与原始帖子的更新中所述相同。

问题#2和#3只是我错误地使用NSUndoManager。我的最终unClear方法(在undos上调用如下:

-(void)undoClear:(NSString *)textToRestore
{   
    NSString *textBackup = [self.myTextView.text copy];

    self.myTextView.text = textToRestore;

    if ([self.myTextView.undoManager isUndoing])
    {
        // Prepare the redo.
        [[self.myTextView.undoManager prepareWithInvocationTarget:self] undoClear:@""];     
    }
    else if ([self.myTextView.undoManager isRedoing])
    {
        [[self.myTextView.undoManager prepareWithInvocationTarget:self] undoClear:textBackup];
    }

    [textBackup release];
}

它现在应该正常工作。

答案 1 :(得分:1)

您可以将textview更改为您想要的任何文本,并保留undo和redo manager的内存堆栈。 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];
    }

答案 2 :(得分:0)

我不会起诉你正在使用多少文本字段,但textBackup未被prepareWithInvocationTarget:保留。如何在撤消堆栈中保留几个明文?看起来它可能仍然存在于第一个之后,但不是在第二个之后或在Autorelease池刷新之后。