简体   繁体   English

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

[英]How to group keystrokes for NSUndoManager+UITextInput

I have a view that implements UITextInput and I added support for undo. 我有一个实现UITextInput的视图,并且添加了对撤消的支持。 Right now each individual key stroke or backspace is recorded as an undoable event. 现在,每个单独的按键或退格键都记录为一个不可撤消的事件。

I know that I can group events and I can open an undo group with the first key stroke. 我知道我可以对事件进行分组,并且可以通过第一个按键来打开撤消组。 But where would I go and close the group? 但是我要去哪里关闭小组? If the group is open when the user shakes the device I get an exception. 如果当用户摇动设备时该组处于打开状态,我将获得例外。 You cannot have an open group when doing undo. 撤消操作时,您不能有一个开放的组。

I would somehow need to close the open group right before the NSUndoManager instance displays the action menu. 我将需要在NSUndoManager实例显示操作菜单之前关闭打开的组。

Do I need to subclass NSUndoManager to do that? 我需要子类化NSUndoManager来做到这一点吗? Or does anybody have a smart idea how I get to close the typing undo group in time before the action? 还是有人有一个聪明的主意,我该如何在采取行动之前及时关闭撤消撤消小组?

Note: first responder does not resign when showing the undo actions. 注意:显示撤消操作时,第一响应者不会辞职。

Actually it looks to me like normal text input leaves the typing group somehow open, because if you cancel the undo/redo alert, then you can continue typing and all those keystrokes can subsequently be undone together. 实际上,在我看来,就像普通文本输入会使键入组处于某种打开状态一样,因为如果您取消撤消/重做警报,则可以继续键入并且随后可以撤消所有这些击键。

I guess I don't understand when to group actions and whether and when you need to close a group. 我想我不知道何时将动作分组以及是否以及何时需要结束群组。

Update: I found the following to be working: I have created a subclass of NSUndoManager that keeps track of the number of open groups. 更新:我发现以下工作正常:我创建了NSUndoManager的子类,该子类跟踪打开的组的数量。 On -undo I'm closing all open groups to avoid the exception and then call [super undo] 在-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

Whenever a new operation begins, like changing paragraph style, I call [self.undoManager closeAllOpenGroups] which causes the undo group for the typing to be closed. 每当开始新操作(例如更改段落样式)时,我都会调用[self.undoManager closeAllOpenGroups] ,这将导致用于键入的撤消组被关闭。

in the -deleteBackward: and -insertText: methods I know that a new typing block needs to be be started: -deleteBackward:-insertText:方法中,我知道需要启动一个新的键入块:

- (void)insertText:(NSString *)text
{
    DTUndoManager *undoManager = (DTUndoManager *)self.undoManager;
    if (!undoManager.numberOfOpenGroups)
    {
        [self.undoManager beginUndoGrouping];
    }

Now that is not too much extra code, but I was hoping to not having to work with my own subclass for DTUndoManager... so I'm open for suggestions. 现在不需要太多额外的代码,但是我希望不必为DTUndoManager使用自己的子类...所以我愿意征求建议。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM