Disable undo / redo in Cocoa app

I have implemented undo / redo in the standard way (NSUndoManager), but I cannot figure out how to disable undo / redo when my application is in a certain state.

Users draw things in my application, and when they load, I turned off the user interface and, of course, I do not want the user to be able to undo / redo.

I am using NSView Undo Manager, so I assume that one of the ways could be to simply cancel the first responder from this view. Is there another way?

+5
source share
5 answers

You can complete the cancellation and retry with

 - (void) removeAllActions;

or delete actions for a specific purpose using

 - (void) removeAllActionsWithTarget: (id) target;

- , , "/", NSMenuValidationProtocol

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

, validateMenuItem: .

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

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

, /, ( / ).

- (BOOL)validateMenuItem:(NSMenuItem *)item ( 10.12). https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MenuList/Articles/EnablingMenuItems.html:

, , NSMenu , validateMenuItem: validateUserInterfaceItem:. , . , .

, .

, , NSWindow , undo: ( ), NSWindow validateMenuItem, :

#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, .

0

, , , -undoManager nil , / .

( , 99% , , .)

-1

The documentation is your friend. The disableUndoRegistration method of NSUndoManager has disabled its name. It is up to your application controllers to decide when it is necessary to disable and re-enable deregistration.

-1
source

All Articles