1、简介

  UIResponder有个属性:NSUndoManager

@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

#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 +=;
self.btnView.frame = rect;
}
- (void)btnViewReduce{
[[_undoManager prepareWithInvocationTarget:self] btnViewAdd];
CGRect rect = self.btnView.frame;
rect.origin.x -=;
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 = ; //可撤销的撤消和重做操作
@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

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. 【算法】BitMap

    转自:https://www.seoxiehui.cn/article-45186-1.html 需求: 为满足用户标签的统计需求,小灰利用Mysql设计了如下的表结构,每一个维度的标签都对应着Mys ...

  2. ac自动机暴力跳fail匹配——hdu5880

    很简单的题,ac自动机里再维护一个len表示每个状态的串长,用s去query时每到一个结点都要暴力跳fail,因为有可能这个结点不是,但是其fail是危险结点,找到一个就直接break 再用个差分数组 ...

  3. App应用推广

    Android应用推广渠道: 360手机助手: http://dev.360.cn/ 应用宝: http://open.qq.com/ 百度手机助手: http://shouji.baidu.com/ ...

  4. 文件上传 和 base64编码

    base64编码 1.关于Base64编码  :  https://www.cnblogs.com/liyiwen/p/3814968.html (个人猜测),file表单发送文件,肯定是将文件转换为 ...

  5. 排序算法(三)堆排序及有界堆排序Java实现及分析

    1.堆排序基数排序适用于大小有界的东西,除了他之外,还有一种你可能遇到的其它专用排序算法:有界堆排序.如果你在处理非常大的数据集,你想要得到前 10 个或者前k个元素,其中k远小于n,它是很有用的. ...

  6. Arduino与水泵实验+土壤湿度传感器

    1 水泵实验我们这里是使用的继电器控制的水泵,注意再实验的时候电池的电压不要超过6v,太大容易烧毁水泵,如果是长时间的使用水泵,要注意将水泵放入水中,这样可以达到给水泵降温的效果.1.全新5V继电器模 ...

  7. 20165239 2018——2019Exp8 Web基础

    Exp8 Web基础 基础问题回答 (1)什么是表单 •表单在网页中主要负责数据采集功能. •一个表单有三个基本组成部分: ◦表单标签,这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务 ...

  8. ACdream 1157 (cdq分治)

    题目链接 Segments Time Limit: 4000/2000MS (Java/Others)Memory Limit: 20000/10000KB (Java/Others) Problem ...

  9. RabbitMQ使用(一)

    1. 安装与使用 1. 激活 RabbitMQ's Management Plugin (前面跟绝对路径) "D:\娱乐\rabbitmq_server-3.6.5\sbin\rabbitm ...

  10. python TypeError: ‘encoding’ is an invalid keyword argument for this function

    shell调用python脚本出现了这个问题,查询原因得知,python脚本是python3.6写的,我们服务器上默认的python是python2.7.3,所以会出现编码问题. 解决思路: 1.安装 ...