如何对 NSUndoManager+UITextInput 的击键进行分组

Posted

技术标签:

【中文标题】如何对 NSUndoManager+UITextInput 的击键进行分组【英文标题】:How to group keystrokes for NSUndoManager+UITextInput 【发布时间】:2012-12-19 14:21:19 【问题描述】:

我有一个实现 UITextInput 的视图,并添加了对撤消的支持。现在,每个单独的击键或退格键都被记录为可撤消的事件。

我知道我可以对事件进行分组,并且可以通过第一次击键打开一个撤消组。但是我该去哪里关闭这个小组呢?如果当用户摇动设备时该组是打开的,我会得到一个例外。撤消时不能有一个打开的组。

我需要在 NSUndoManager 实例显示操作菜单之前关闭打开的组。

我是否需要继承 NSUndoManager 才能做到这一点?或者有人知道如何在操作之前及时关闭输入撤消组吗?

注意:第一响应者在显示撤消操作时不会辞职。

实际上,在我看来,正常的文本输入会以某种方式打开打字组,因为如果您取消撤消/重做警报,那么您可以继续打字,所有这些击键随后都可以一起撤消。

我想我不明白何时对操作进行分组,以及是否以及何时需要关闭组。

更新:我发现以下工作正常:我创建了一个 NSUndoManager 的子类,用于跟踪打开组的数量。在 -undo 上,我将关闭所有打开的组以避免异常,然后调用 [super undo]

#import "DTUndoManager.h"

@implementation DTUndoManager

    NSUInteger _numberOfOpenGroups;


- (void)beginUndoGrouping

    _numberOfOpenGroups++;

    [super beginUndoGrouping];


- (void)endUndoGrouping

    _numberOfOpenGroups--;

    [super endUndoGrouping];


- (void)closeAllOpenGroups

    while (_numberOfOpenGroups>0)
    
        [self endUndoGrouping];
    


- (void)undo

    [self closeAllOpenGroups];

    [super undo];


#pragma mark - Properties

@synthesize numberOfOpenGroups = _numberOfOpenGroups;

@end

每当一个新操作开始时,比如更改段落样式,我都会调用[self.undoManager closeAllOpenGroups],这会导致关闭输入的撤消组。

-deleteBackward:-insertText: 方法中,我知道需要启动一个新的打字块:

- (void)insertText:(NSString *)text

    DTUndoManager *undoManager = (DTUndoManager *)self.undoManager;
    if (!undoManager.numberOfOpenGroups)
    
        [self.undoManager beginUndoGrouping];
    

现在这不是太多额外的代码,但我希望不必使用我自己的 DTUndoManager 子类...所以我愿意接受建议。

【问题讨论】:

我在 ios 上不是很方便,而在 cocoa 上,我只会使用撤消和重做管理器菜单项创建一个出口,然后禁用它们。在 iOS 中,用户如何选择撤消和重做? 【参考方案1】:

我的解决方案包含在问题的更新中。

【讨论】:

以上是关于如何对 NSUndoManager+UITextInput 的击键进行分组的主要内容,如果未能解决你的问题,请参考以下文章

CoreData NSUndoManager 关系问题

NSUndoManager 灾难

自动保存不适用于 UIManagedDocument 上的 NSUndoManager

NSUndoManager 检测核心数据实体的实际删除

Xcode LLDB 打印语句失败 - NSUndoManager

UITextView 和 NSUndoManager 同步