Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Cocoa应用程序中禁用撤消/重做_Cocoa_Undo_Nsundomanager - Fatal编程技术网

在Cocoa应用程序中禁用撤消/重做

在Cocoa应用程序中禁用撤消/重做,cocoa,undo,nsundomanager,Cocoa,Undo,Nsundomanager,我已经用标准方式(NSUndoManager)实现了撤销/重做,但我不知道在我的应用程序处于特定状态时如何禁用撤销/重做 用户在我的应用程序中绘制东西,当他们绘制的东西上传时,我禁用UI,当然不希望用户能够撤消/重做 我使用NSView的撤销管理器,所以我想一种方法可能是让该视图成为第一响应者。还有其他方法吗?我能想到的最佳方法是使视图的-undoManager方法在上载期间返回nil,这将从响应程序链中删除它,并导致该视图的撤消/重做选项被禁用 (我还没有对此进行测试,但我99%确信,每当菜单

我已经用标准方式(NSUndoManager)实现了撤销/重做,但我不知道在我的应用程序处于特定状态时如何禁用撤销/重做

用户在我的应用程序中绘制东西,当他们绘制的东西上传时,我禁用UI,当然不希望用户能够撤消/重做


我使用NSView的撤销管理器,所以我想一种方法可能是让该视图成为第一响应者。还有其他方法吗?

我能想到的最佳方法是使视图的
-undoManager
方法在上载期间返回nil,这将从响应程序链中删除它,并导致该视图的撤消/重做选项被禁用


(我还没有对此进行测试,但我99%确信,每当菜单验证菜单选项时,它将向您的视图询问撤消管理器。)

您可以使用完成撤消和重做

 - (void) removeAllActions;
或使用删除特定目标的操作

 - (void) removeAllActionsWithTarget: (id) target;
如果您只是想在一段时间内禁用任何操作,保持撤消堆栈不变,只需使用NSMenuValidationProtocol的

 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem;

如果视图是第一响应程序,则可以根据当前状态实现协议以禁用或启用菜单项

 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
     SEL action = menuItem.action;

     if (action == @selector(undo:) ||
         action == @selector(redo:)) {
          return !uploadingImage;
     }
     return YES;
 }

文档是您的朋友。NSUndoManager的方法名称中有“disable”。由应用程序的控制器决定何时应禁用和重新启用撤消注册。

我遇到过类似的情况,我想在应用程序处于特定状态时有条件地禁用某些撤消/重做操作(同时仍允许对其他操作执行撤消/重做)

在视图上实现
-(BOOL)validateNuItem:(NSMenuItem*)项
的方法对我不起作用(我有一个基于10.12的文档应用程序)。根据以下文件:

如果响应程序链中有一个对象实现了该项的操作,则NSMenu会检查该对象是否实现了ValidateNuItem:或validateUserInterfaceItem:方法。如果没有,则菜单项已启用。如果是,则菜单项的启用状态由方法的返回值确定

视图必须添加一个undo方法,该方法也可以做正确的事情

当我探测响应器链时,我发现我的NSWindow是响应
撤消:
(虽然它不是文档化接口的一部分)的对象,因此我当前的计划是使用自定义NSWindow子类,并在IME实现
ValidateNuItem
,大致如下:

#import "Window.h"

@implementation SBXWindow

- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSWindowStyleMask)style backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag screen:(NSScreen *)screen
{
    self = [super initWithContentRect:contentRect styleMask:style backing:bufferingType defer:flag screen:screen];

    return self;
}


- (BOOL)validateMenuItem:(NSMenuItem *)item
{
    // Call super imeplementation as it appears to update the menu item title (and potentially other stuff)
    BOOL result = [super validateMenuItem:item];
    if (result == NO) {
        return NO;
    }

    if (item.action == @selector(undo:) || item.action == @selector(redo:)) {
        // Add custom logic here
    }

    return result;
}

@end
但是,存在以下警告:
undo:
redo:
方法未实现。可以通过在NSWindow上创建一个类别来消除这些问题,例如:

@interface NSWindow (SBXUndoable)

- (void)undo:(id)sender;
- (void)redo:(id)sender;

@end

不确定这样做是否有任何问题(我没有注意到),但它确实消除了警告。此后,我将该类更改为Swift类,该类没有任何警告需要处理。

是的。成功了。必须实现(iAction)撤销:(id)发送方。这是关于撤销事件的设置,而不是禁用撤销/重做菜单。