demo网址:NSUndoManager下载
我的个人博客:http://blog.csdn.net/FloatingDreamSH
我的Github: https://github.com
#pragma mark - 先将此视图放在UINavigationController中
//
// ViewController.m
// NSUndoManager
//
// Created by HarrySun on 16/7/28.
// Copyright © 2016年 Mobby. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong)UILabel *myLabel;
@property (nonatomic,strong)NSUndoManager *undoManager;
@property (assign)int num;
@end
@implementation ViewController
@synthesize undoManager;
/*
NSUndoManager会记录下修改、撤销操作的消息。这个机制使用两个NSInvocation对象栈。
NSInvocation会把消息(选择器和接受者及参数)包装成一个对象,这个对象就是NSInvocation的实例。当一个对象收到它不理解的消息时,消息发送机制会在报出错误前检查该对象是否实现了forwardInvocation这个方法。如果实现了,就会将消息打包成NSInvocation对象,然后调用forwardInvocation方法。
NSUndoManager工作原理:
当进行操作时,控制器会添加一个该操作的逆操作的invocation到Undo栈中。当进行Undo操作时,Undo操作的逆操作会被添加到Redo栈中,就这样利用Undo和Redo两个堆栈巧妙的实现撤销操作。
*/
- (void)viewDidLoad {
[superviewDidLoad];
_myLabel = [[UILabelalloc]initWithFrame:CGRectMake(100,300,100, 100)];
_myLabel.backgroundColor = [UIColorcyanColor];
_myLabel.userInteractionEnabled =YES;
[self.viewaddSubview:_myLabel];
UIButton * addButton = [UIButtonbuttonWithType:UIButtonTypeRoundedRect];
[addButton setFrame:CGRectMake(100,420,100,50)];
[addButton setTitle:@"Add"forState:UIControlStateNormal];
[addButton addTarget:selfaction:@selector(add)forControlEvents:UIControlEventTouchUpInside];
[self.viewaddSubview:addButton];
undoManager = [[NSUndoManageralloc]init]; //初始化UndoManager
[undoManagersetLevelsOfUndo:999]; // 设置最大极限,当达到极限时扔掉旧的撤销,0则是没有界限
_num =0;
}
#pragma mark - NSUndoManager 操作
// 在我们的程序中有add以及这个方法的逆方法substract,我们可以这样来实现撤销功能。
-(void)substract{
_num -=10;
[[undoManagerprepareWithInvocationTarget:self]add];
_myLabel.text = [NSStringstringWithFormat:@"%d",_num];
[selfsetTheUI];
}
-(void)add{
_num +=10;
[[undoManagerprepareWithInvocationTarget:self]substract]; //基于NSInvocation触发undo
// prepareWithInvocationTarget:方法记录了target并返回UndoManager,然后UndoManager重载了forwardInvocation方法,也就将substract方法的Invocation添加到undo栈中了。
_myLabel.text = [NSStringstringWithFormat:@"%d",_num];
[selfsetTheUI];
}
-(void)undo{
// 执行撤销
[self.undoManagerundo]; //注意这里不是[self undo];
}
-(void)redo{
// 执行反撤销
[self.undoManagerredo];
}
// 根据num的值判断是否加navigationItem
-(void)setTheUI{
if (!_num){
self.navigationItem.rightBarButtonItem = nil;
}else{
UIBarButtonItem * barButtonItem = [[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemUndotarget:selfaction:@selector(undo)]; // 方法没有冒号
self.navigationItem.rightBarButtonItem = barButtonItem;
}
if (!_num){
self.navigationItem.leftBarButtonItem = nil;
}else{
UIBarButtonItem * barButtonItem = [[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemRedotarget:selfaction:@selector(redo)];
self.navigationItem.leftBarButtonItem = barButtonItem;
}
}
- (void)didReceiveMemoryWarning {
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end