美文网首页
iOS开发UIResponder之NSUndoManager

iOS开发UIResponder之NSUndoManager

作者: 街角仰望 | 来源:发表于2020-04-24 15:55 被阅读0次

    1、简介

    UIResponder有个属性:NSUndoManager

     @property(nullable, nonatomic,readonly) NSUndoManager *undoManager NS_AVAILABLE_IOS(3_0);
    

    NSUndoManager可以叫做撤销管理器,可以撤销和重做,类似快捷键command+zcommand+shift+z
    NSUndoManger内部维护两个栈,undo栈(撤销)和redo栈(重写)。

    2、NSUndoManger的简单使用

    2.1、数组的undo和redo

    代码:

    #import "UndoTest.h"
    
    @interface UndoTest()
    @end
    @implementation UndoTest
    
    - (instancetype)init{
        if (self = [super init]) {
            self.undoManager = [[NSUndoManager alloc] init];
            self.undoArr = [NSMutableArray array];
        }
        return self;
    }
    - (void)addObjectMethod:(NSString *)anObject{
        [[self.undoManager prepareWithInvocationTarget:self] removeObjectMehtod:anObject];
        [self.undoArr addObject:anObject];
    }
    - (void)removeObjectMehtod:(NSString *)anObject{
        [[self.undoManager prepareWithInvocationTarget:self] addObjectMethod:anObject];
        if ([self.undoArr containsObject:anObject]) {
            [self.undoArr removeObject:anObject];
        }
    }
    
    @end
    
    UndoTest代码
    

    效果:

    2.2、视图移动的undo和redo

    代码:

    - (void)viewDidLoad {
        [super viewDidLoad];
        _undoManager = [[NSUndoManager alloc] init];
    }
    - (void)btnViewAdd{
        [[_undoManager prepareWithInvocationTarget:self] btnViewReduce];
        CGRect rect = self.btnView.frame;
        rect.origin.x +=10;
        self.btnView.frame = rect;
    }
    - (void)btnViewReduce{
        [[_undoManager prepareWithInvocationTarget:self] btnViewAdd];
        CGRect rect = self.btnView.frame;
        rect.origin.x -=10;
        self.btnView.frame = rect;
    }
    - (IBAction)addClick:(id)sender {
        [self btnViewAdd];
    }
    - (IBAction)reduceClick:(id)sender {
        [self btnViewReduce];
    }
    
    - (IBAction)undoClick:(UIButton *)sender {
        [_undoManager undo];
    }
    - (IBAction)redoClick:(UIButton *)sender {
        [_undoManager redo];
    }
    
    视图移动代码
    

    效果:

    3、NSUndoManger的相关API

    NS_CLASS_AVAILABLE(10_0, 3_0)
    @interface NSUndoManager : NSObject {
    @private
        id             _undoStack;
        id             _redoStack;
        NSArray         *_runLoopModes;
        uint64_t        _NSUndoManagerPrivate1;
        id             _target;
        id            _proxy;
        void        *_NSUndoManagerPrivate2;
        void        *_NSUndoManagerPrivate3;
    }
    
    //创建撤销组
    - (void)beginUndoGrouping;  //开始
    - (void)endUndoGrouping;    //结束
    @property BOOL groupsByEvent; //默认启用,自动分组,一个RunLoop事件中注册的所有undomanager为一个顶级组
    @property (readonly) NSInteger groupingLevel;//组等级
    
    //启用和禁用撤消
    - (void)disableUndoRegistration;
    - (void)enableUndoRegistration;
    @property (readonly, getter=isUndoRegistrationEnabled) BOOL undoRegistrationEnabled;
    
    /* Groups By Event */
    
    
    //限制撤销堆栈
    @property NSUInteger levelsOfUndo;
    
    //在运行循环的周期内处理输入类型的模式。
    @property (copy) NSArray<NSRunLoopMode> *runLoopModes;
    
    //执行撤消和重做
    - (void)undo;
    - (void)redo;
    - (void)undoNestedGroup;
    
    //检查撤销能力
    @property (readonly) BOOL canUndo;
    @property (readonly) BOOL canRedo;
    
    //检查是否正在执行撤消或重做
    @property (readonly, getter=isUndoing) BOOL undoing;
    @property (readonly, getter=isRedoing) BOOL redoing;
    
    //移除撤销操作
    - (void)removeAllActions;
    - (void)removeAllActionsWithTarget:(id)target;
    
    //注册撤消操作
    - (void)registerUndoWithTarget:(id)target selector:(SEL)selector object:(nullable id)anObject;
    - (id)prepareWithInvocationTarget:(id)target;
    - (void)registerUndoWithTarget:(id)target handler:(void (^)(id target))undoHandler API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) NS_REFINED_FOR_SWIFT;
    
    //如果撤销组作为一个整体被丢弃,则该密钥具有对应的true值。
    FOUNDATION_EXPORT NSString * const NSUndoManagerGroupIsDiscardableKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
    // used with NSRunLoop's performSelector:target:argument:order:modes:
    static const NSUInteger NSUndoCloseGroupingRunLoopOrdering = 350000;
    
    //可撤销的撤消和重做操作
    @property (readonly) BOOL undoActionIsDiscardable API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
    @property (readonly) BOOL redoActionIsDiscardable API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
    - (void)setActionIsDiscardable:(BOOL)discardable API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
    
    //管理操作名字
    @property (readonly, copy) NSString *undoActionName;
    @property (readonly, copy) NSString *redoActionName;
    - (void)setActionName:(NSString *)actionName;
    
    //获取和本地化菜单项标题
    @property (readonly, copy) NSString *undoMenuItemTitle;
    @property (readonly, copy) NSString *redoMenuItemTitle;
    - (NSString *)undoMenuTitleForUndoActionName:(NSString *)actionName;
    - (NSString *)redoMenuTitleForUndoActionName:(NSString *)actionName;
    
    @end
    //通知
    //打开或关闭撤销组
    FOUNDATION_EXPORT NSNotificationName const NSUndoManagerCheckpointNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
    //将要执行一个撤销操作
    FOUNDATION_EXPORT NSNotificationName const NSUndoManagerWillUndoChangeNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
    //将要执行重做操作
    FOUNDATION_EXPORT NSNotificationName const NSUndoManagerWillRedoChangeNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
    //已经执行一个撤销操作
    FOUNDATION_EXPORT NSNotificationName const NSUndoManagerDidUndoChangeNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
    //已经执行重做操作
    FOUNDATION_EXPORT NSNotificationName const NSUndoManagerDidRedoChangeNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
    
    //已经打开一个撤销组时 beginUndoGrouping
    FOUNDATION_EXPORT NSNotificationName const NSUndoManagerDidOpenUndoGroupNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
    //将要关闭一个撤销组时 endUndoGrouping
    FOUNDATION_EXPORT NSNotificationName const NSUndoManagerWillCloseUndoGroupNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
    //已经关闭一个撤销组时 endUndoGrouping
    FOUNDATION_EXPORT NSNotificationName const NSUndoManagerDidCloseUndoGroupNotification API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
    
    NS_ASSUME_NONNULL_END
    

    参考:https://www.cnblogs.com/xianfeng-zhang/p/9481957.html

    相关文章

      网友评论

          本文标题:iOS开发UIResponder之NSUndoManager

          本文链接:https://www.haomeiwen.com/subject/rgacoctx.html