1、简介

  UIResponder有个属性:NSUndoManager

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

  NSUndoManager可以叫做撤销管理器,可以撤销和重做,类似快捷键command+z和command+shift+z;

  NSUndoManger内部维护两个栈,undo栈(撤销)和redo栈(重写)。

2、NSUndoManger的简单使用

  2.1、数组的undo和redo

  1. #import "UndoTest.h"
  2.  
  3. @interface UndoTest()
  4. @end
  5. @implementation UndoTest
  6.  
  7. - (instancetype)init{
  8. if (self = [super init]) {
  9. self.undoManager = [[NSUndoManager alloc] init];
  10. self.undoArr = [NSMutableArray array];
  11. }
  12. return self;
  13. }
  14. - (void)addObjectMethod:(NSString *)anObject{
  15. [[self.undoManager prepareWithInvocationTarget:self] removeObjectMehtod:anObject];
  16. [self.undoArr addObject:anObject];
  17. }
  18. - (void)removeObjectMehtod:(NSString *)anObject{
  19. [[self.undoManager prepareWithInvocationTarget:self] addObjectMethod:anObject];
  20. if ([self.undoArr containsObject:anObject]) {
  21. [self.undoArr removeObject:anObject];
  22. }
  23. }
  24.  
  25. @end

UndoTest代码

  2.2、视图移动的undo和redo

  1. - (void)viewDidLoad {
  2. [super viewDidLoad];
  3. _undoManager = [[NSUndoManager alloc] init];
  4. }
  5. - (void)btnViewAdd{
  6. [[_undoManager prepareWithInvocationTarget:self] btnViewReduce];
  7. CGRect rect = self.btnView.frame;
  8. rect.origin.x +=;
  9. self.btnView.frame = rect;
  10. }
  11. - (void)btnViewReduce{
  12. [[_undoManager prepareWithInvocationTarget:self] btnViewAdd];
  13. CGRect rect = self.btnView.frame;
  14. rect.origin.x -=;
  15. self.btnView.frame = rect;
  16. }
  17. - (IBAction)addClick:(id)sender {
  18. [self btnViewAdd];
  19. }
  20. - (IBAction)reduceClick:(id)sender {
  21. [self btnViewReduce];
  22. }
  23.  
  24. - (IBAction)undoClick:(UIButton *)sender {
  25. [_undoManager undo];
  26. }
  27. - (IBAction)redoClick:(UIButton *)sender {
  28. [_undoManager redo];
  29. }

视图移动代码

3、NSUndoManger的相关API

  1. NS_CLASS_AVAILABLE(10_0, 3_0)
  2. @interface NSUndoManager : NSObject {
  3. @private
  4. id _undoStack;
  5. id _redoStack;
  6. NSArray *_runLoopModes;
  7. uint64_t _NSUndoManagerPrivate1;
  8. id _target;
  9. id _proxy;
  10. void *_NSUndoManagerPrivate2;
  11. void *_NSUndoManagerPrivate3;
  12. }
  13.  
  14. //创建撤销组
  15. - (void)beginUndoGrouping; //开始
  16. - (void)endUndoGrouping; //结束
  17. @property BOOL groupsByEvent; //默认启用,自动分组,一个RunLoop事件中注册的所有undomanager为一个顶级组
  18. @property (readonly) NSInteger groupingLevel;//组等级
  19.  
  20. //启用和禁用撤消
  21. - (void)disableUndoRegistration;
  22. - (void)enableUndoRegistration;
  23. @property (readonly, getter=isUndoRegistrationEnabled) BOOL undoRegistrationEnabled;
  24.  
  25. /* Groups By Event */
  26.  
  27. //限制撤销堆栈
  28. @property NSUInteger levelsOfUndo;
  29.  
  30. //在运行循环的周期内处理输入类型的模式。
  31. @property (copy) NSArray<NSRunLoopMode> *runLoopModes;
  32.  
  33. //执行撤消和重做
  34. - (void)undo;
  35. - (void)redo;
  36. - (void)undoNestedGroup;
  37.  
  38. //检查撤销能力
  39. @property (readonly) BOOL canUndo;
  40. @property (readonly) BOOL canRedo;
  41.  
  42. //检查是否正在执行撤消或重做
  43. @property (readonly, getter=isUndoing) BOOL undoing;
  44. @property (readonly, getter=isRedoing) BOOL redoing;
  45.  
  46. //移除撤销操作
  47. - (void)removeAllActions;
  48. - (void)removeAllActionsWithTarget:(id)target;
  49.  
  50. //注册撤消操作
  51. - (void)registerUndoWithTarget:(id)target selector:(SEL)selector object:(nullable id)anObject;
  52. - (id)prepareWithInvocationTarget:(id)target;
  53. - (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;
  54.  
  55. //如果撤销组作为一个整体被丢弃,则该密钥具有对应的true值。
  56. FOUNDATION_EXPORT NSString * const NSUndoManagerGroupIsDiscardableKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
  57. // used with NSRunLoop's performSelector:target:argument:order:modes:
  58. static const NSUInteger NSUndoCloseGroupingRunLoopOrdering = ;
  59.  
  60. //可撤销的撤消和重做操作
  61. @property (readonly) BOOL undoActionIsDiscardable API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
  62. @property (readonly) BOOL redoActionIsDiscardable API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
  63. - (void)setActionIsDiscardable:(BOOL)discardable API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
  64.  
  65. //管理操作名字
  66. @property (readonly, copy) NSString *undoActionName;
  67. @property (readonly, copy) NSString *redoActionName;
  68. - (void)setActionName:(NSString *)actionName;
  69.  
  70. //获取和本地化菜单项标题
  71. @property (readonly, copy) NSString *undoMenuItemTitle;
  72. @property (readonly, copy) NSString *redoMenuItemTitle;
  73. - (NSString *)undoMenuTitleForUndoActionName:(NSString *)actionName;
  74. - (NSString *)redoMenuTitleForUndoActionName:(NSString *)actionName;
  75.  
  76. @end
  77. //通知
  78. //打开或关闭撤销组
  79. FOUNDATION_EXPORT NSNotificationName const NSUndoManagerCheckpointNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
  80. //将要执行一个撤销操作
  81. FOUNDATION_EXPORT NSNotificationName const NSUndoManagerWillUndoChangeNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
  82. //将要执行重做操作
  83. FOUNDATION_EXPORT NSNotificationName const NSUndoManagerWillRedoChangeNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
  84. //已经执行一个撤销操作
  85. FOUNDATION_EXPORT NSNotificationName const NSUndoManagerDidUndoChangeNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
  86. //已经执行重做操作
  87. FOUNDATION_EXPORT NSNotificationName const NSUndoManagerDidRedoChangeNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
  88.  
  89. //已经打开一个撤销组时 beginUndoGrouping
  90. FOUNDATION_EXPORT NSNotificationName const NSUndoManagerDidOpenUndoGroupNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
  91. //将要关闭一个撤销组时 endUndoGrouping
  92. FOUNDATION_EXPORT NSNotificationName const NSUndoManagerWillCloseUndoGroupNotification API_AVAILABLE(macos(10.0), ios(3.0), watchos(2.0), tvos(9.0));
  93. //已经关闭一个撤销组时 endUndoGrouping
  94. FOUNDATION_EXPORT NSNotificationName const NSUndoManagerDidCloseUndoGroupNotification API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
  95.  
  96. NS_ASSUME_NONNULL_END

iOS开发UIResponder之NSUndoManager的更多相关文章

  1. iOS开发UIResponder简介API

    #import <Foundation/Foundation.h> #import <UIKit/UIKitDefines.h> #import <UIKit/UIEve ...

  2. 【IOS开发笔记02】学生管理系统

    端到端的机会 虽然现在身处大公司,但是因为是内部创业团队,产品.native.前端.服务器端全部坐在一起开发,大家很容易做零距离交流,也因为最近内部有一个前端要转岗过来,于是手里的前端任务好像可以抛一 ...

  3. ios开发中的小技巧

    在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIViewal ...

  4. iOS开发系列--IOS程序开发概览

    概览 终于到了真正接触IOS应用程序的时刻了,之前我们花了很多时间去讨论C语言.ObjC等知识,对于很多朋友而言开发IOS第一天就想直接看到成果,看到可以运行的IOS程序.但是这里我想强调一下,前面的 ...

  5. iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控

    -- iOS事件全面解析 概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实是可以不用按键和手写笔直接操作的,这不愧为一项伟大的设计.今天我们就针对iOS的触摸事 ...

  6. iOS开发-UI 从入门到精通(三)

    iOS开发-UI 从入门到精通(三)是对 iOS开发-UI 从入门到精通(一)知识点的综合练习,搭建一个简单地登陆界面,增强实战经验,为以后做开发打下坚实的基础! ※在这里我们还要强调一下,开发环境和 ...

  7. iOS开发——UI精选OC篇&UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍

    UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍 一:UIApplication:单例(关于单例后面的文章中会详细介绍,你现在只要知道 ...

  8. IOS开发常用设计模式

    IOS开发常用设计模式 说起设计模式,感觉自己把握不了笔头,所以单拿出iOS开发中的几种常用设计模式谈一下. 单例模式(Singleton) 概念:整个应用或系统只能有该类的一个实例 在iOS开发我们 ...

  9. 解析iOS开发中的FirstResponder第一响应对象

    1. UIResonder 对于C#里所有的控件(例如TextBox),都继承于Control类.而Control类的继承关系如下: 代码如下: System.Object System.Marsha ...

随机推荐

  1. tp5使用jwt生成token,做api的用户认证

    首先 composer 安装  firebase/php-jwt github:https://github.com/firebase/php-jwt composer require firebas ...

  2. Java-Class-C:com.github.pagehelper.PageInfo

    ylbtech-Java-Class-C:com.github.pagehelper.PageInfo 1.返回顶部   2.返回顶部 1.1. import com.github.pagehelpe ...

  3. IIS身份验证和文件操作权限(二、匿名身份验证)

    一.配置匿名身份验证 二.浏览站点 -- 操作文件 ①无操作权限 点击写入 ②有操作权限(IIS_IUSRS.Authenticated Users两个任选一个) 点击写入

  4. 自旋锁spinlock

    1 在单处理器上的实现 单核系统上,不存在严格的并发,因此对资源的共享主要是多个任务分时运行造成的. 只要在某一时段,停止任务切换,并且关中断(对于用户态应用程序,不大可能与中断处理程序抢临界区资源) ...

  5. 条件sql ibatis

    <!-- 多条件查询 --><select id="MS-CUSTOM-PANDECT-INFO-BY-CONDITIONS" resultMap="R ...

  6. [已解决]报错JSONDecodeError

    报错: 解决:

  7. [Code+#3]博弈论与概率统计

    题目 记得曾经和稳稳比谁后抄这个题的题解,看来是我输了 不难发现\(p\)是给着玩的,只需要求一个总情况数除以\(\binom{n+m}{n}\)就好了 记\(i\)为无效的失败次数,即\(\rm A ...

  8. dp思维

    题目传输门 题意:有n个房间,m个诅咒,每个房间有一个数值,刚开始有一个初始值,每次进入一个房间可以选择消除诅咒或者不消除,消除诅咒只能顺序消除,消除诅咒就是拿初始值和房间的数值做运算,求最后最大的数 ...

  9. Vue番外篇-路由进阶(一)

    Vue的router默认是 export default new Router({ mode: 'history', routes: [ { path: '/', name: 'HelloWorld' ...

  10. java oop第10章_JDBC03(MVC分层模式)

    引言:在进行程序开发的时候,为了更加利于程序的管理我们引入了新的开发模式MVC分层模式,即按功能将程序代码分别分为M(Model模型).V(View视图).C(Controller控制器)三个组成部分 ...