一、簡介ios
UIResponder有個屬性:NSUndoManagermacos
@property(nullable, nonatomic,readonly) NSUndoManager *undoManager NS_AVAILABLE_IOS(3_0);
NSUndoManager能夠叫作撤銷管理器,能夠撤銷和重作,相似快捷鍵command+z和command+shift+z;數組
NSUndoManger內部維護兩個棧,undo棧(撤銷)和redo棧(重寫)。dom
二、NSUndoManger的簡單使用ide
2.一、數組的undo和redooop
#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
2.二、視圖移動的undo和redoui
- (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]; }
三、NSUndoManger的相關APIatom
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