第15章 消息发送模式 下 NSUndoManager 撤销管理器
15.6 撤销构造
Cocoa环境中,为了能够撤销或重复之前的操作,准备了专门的类NSUndoManager(撤销管理器)。
取消之前的操作,可以通过记录操作之前的状态来还愿,或者执行与当前操作效果相反的操作。NSUndoManager根据后者实现了撤销。
应用中运行某种操作时,撤销管理器会同时记录包含逆操作的信息(或信息群),这就是撤销的基本结构。撤销管理器将这些消息有序地记录在撤销栈中,当有撤销请求时,就取出最新的记录内容执行。
//
// ViewController.m
// NSUndoManagerTest
//
// Created by ranzhou on 16/7/3.
// Copyright © 2016年 ranzhouee. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) NSUndoManager *myUndo;
@end
@implementation ViewController
- (void)test1
{
[self.myUndo undo];
/*
2016-07-07 10:23:41.977 NSUndoManagerTest[1011:55134] moveToLeft:-----10
2016-07-07 10:23:41.979 NSUndoManagerTest[1011:55134] moveToRight:-----40
2016-07-07 10:23:41.989 NSUndoManagerTest[1011:55134] moveToRight:-----20
2016-07-07 10:23:41.989 NSUndoManagerTest[1011:55134] moveToLeft:-----30
//调用一次undo,撤销了viewDidAppear:的操作。
2016-07-07 10:23:41.990 NSUndoManagerTest[1011:55134] moveToRight:-----30
2016-07-07 10:23:41.990 NSUndoManagerTest[1011:55134] moveToLeft:-----20
*/
}
- (void)test2
{
/*
2016-07-07 10:25:47.736 NSUndoManagerTest[1040:56521] moveToLeft:-----10
2016-07-07 10:25:47.737 NSUndoManagerTest[1040:56521] moveToRight:-----40
2016-07-07 10:25:47.743 NSUndoManagerTest[1040:56521] moveToRight:-----20
2016-07-07 10:25:47.744 NSUndoManagerTest[1040:56521] moveToLeft:-----30
*/
[self.myUndo undo];
/*
// 第一次undo撤销的操作,viewDidAppear:中的操作。
2016-07-07 10:25:47.744 NSUndoManagerTest[1040:56521] moveToRight:-----30
2016-07-07 10:25:47.744 NSUndoManagerTest[1040:56521] moveToLeft:-----20
*/
[self.myUndo undo];
/*
// 第二次undo撤销的操作,viewDidLoad中的操作。
2016-07-07 10:25:47.745 NSUndoManagerTest[1040:56521] moveToLeft:-----40
2016-07-07 10:25:47.745 NSUndoManagerTest[1040:56521] moveToRight:-----10
*/
}
- (void)test3{
/*
2016-07-07 10:27:43.257 NSUndoManagerTest[1075:57782] moveToLeft:-----10
2016-07-07 10:27:43.258 NSUndoManagerTest[1075:57782] moveToRight:-----40
2016-07-07 10:27:43.262 NSUndoManagerTest[1075:57782] moveToRight:-----20
2016-07-07 10:27:43.262 NSUndoManagerTest[1075:57782] moveToLeft:-----30
*/
[self.myUndo undo];
/*
2016-07-07 10:27:43.263 NSUndoManagerTest[1075:57782] moveToRight:-----30
2016-07-07 10:27:43.263 NSUndoManagerTest[1075:57782] moveToLeft:-----20
*/
[self.myUndo redo];
/*
2016-07-07 10:27:43.263 NSUndoManagerTest[1075:57782] moveToRight:-----20
2016-07-07 10:27:43.263 NSUndoManagerTest[1075:57782] moveToLeft:-----30
*/
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self moveToRight:20];
[self moveToLeft:30];
[self test3];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.myUndo = [[NSUndoManager alloc]init];
[self moveToLeft:10];
[self moveToRight:40];
}
- (void)moveToLeft:(NSInteger)step
{
NSLog(@"%@-----%li",NSStringFromSelector(_cmd),(long)step);
[[self.myUndo prepareWithInvocationTarget:self]moveToRight:step];
}
- (void)moveToRight:(NSInteger)step
{
NSLog(@"%@-----%li",NSStringFromSelector(_cmd),(long)step);
[[self.myUndo prepareWithInvocationTarget:self]moveToLeft:step];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end