4

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

由于只有 firstResponder 获得撤消/重做事件,我想我只需使用 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. 但是,撤消清除和重做清除工作,然后我再次看到“撤消清除”,并且从那里开始不起作用。

有任何想法吗?我接近这个错误吗?

更新:似乎我已经解决了空的撤消项问题:它发生在我调用 prepareWithInvocationTarget后设置 UITextView 的文本时。如果我之前调用它,它不会发生。有趣的是,如果我不调用 prepareWithInvocationTarget (即,通常,当我设置 UITextView 的文本时),空项目不会被推入撤消堆栈。

4

3 回答 3

3

好的,想通了:

#1 的问题在我原始帖子的更新中有所概述。

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

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

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

    [文本备份发布];
}

它现在可以正常工作。

于 2010-11-01T18:00:47.893 回答
1

您可以将您的文本视图更改为您想要的任何文本并保留撤消和重做管理器的内存堆栈。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];
    }
于 2013-10-30T15:12:44.917 回答
0

我不起诉您正在使用多少个文​​本字段,尽管textBackup它没有被保留prepareWithInvocationTarget:如何在几个清除之后仍然在撤消堆栈中?似乎它可能在第一个之后仍然存在,但不是在第二个之后或 Autorelease 池刷新之后。

于 2012-03-20T21:12:51.293 回答