NSUndo Manager的使用

當我們犯錯的時候,系統給了我們犯錯悔改的機會, 系統提供了讓我們回覆或者重做的API---NSUndoManager.

NSUndoManager的基本原理是其中有兩個棧---取消操作的棧和重做操作的棧,棧裏面裝的是NSInvocation對象。當執行一些特定操作後,在取消棧中壓入NSInvocation,其中封裝了消息的消息接受者,方法和參數等。當取消操作時,執行取消棧上棧頂的NSInvocation的消息, 重做的棧裏面會壓入重做的NSInvocation對象。這樣就通過兩個棧和NSInvocation,實現取消操作和重做操作。

例子:有一個TapMe按鈕,點擊後數字加1,Undo按鈕執行取消操作,Redo按鈕執行重做操作,ClearActions執行清除棧的操作。


@interface ViewController ()
{
    IBOutlet UILabel  *mLabel;      //顯示的按鈕
    IBOutlet UIButton *redoButton;  //重做的按鈕
    IBOutlet UIButton *undoButton;  //取消的按鈕
    IBOutlet UIButton *clearButton; //清除的按鈕
    
    int number;                     //總共的點擊次數
    
    NSUndoManager *undoManager;
}

- (IBAction)redoTapped:(id)sender;
- (IBAction)tapMeTapped:(id)sender;
- (IBAction)undoTapped:(id)sender;
- (IBAction)clearTapped:(id)sender;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    undoManager = [[NSUndoManager alloc] init];
    redoButton.hidden = YES;
    undoButton.hidden = YES;
}

//點擊按鈕點擊
- (IBAction)tapMeTapped:(id)sender
{
    [self addNumber];
}

- (void)addNumber
{
    number ++;
    //一個取消操作的NSInvocation對象在Undo棧壓棧---包括取消操作的對象和方法
    [[undoManager prepareWithInvocationTarget:self] subNumber];
    mLabel.text = [NSString stringWithFormat:@"有效點擊數爲%d",number];
    [self refreshpage];
}

- (void)subNumber
{
    number --;
    //一個重新操作的NSInvocation對象在Redo棧壓棧---包括重新操作的對象和方法
    [[undoManager prepareWithInvocationTarget:self] addNumber];
    mLabel.text = [NSString stringWithFormat:@"有效點擊數爲%d",number];
    [self refreshpage];
}

//重做操作
- (IBAction)redoTapped:(id)sender
{
    [undoManager redo]; //Redo棧的Invocation被調用,並被彈出棧
}

//取消操作
- (IBAction)undoTapped:(id)sender
{
    [undoManager undo]; //Undo棧的Invocation被調用,並被彈出棧
}

//clearAction按鈕被點擊
- (IBAction)clearTapped:(id)sender
{
    [undoManager removeAllActions]; //兩個棧裏面的所有NSInvocation對象都被彈出清空
    [self refreshpage];
}

- (void)refreshpage
{
    undoButton.hidden = !undoManager.canUndo;
    redoButton.hidden = !undoManager.canRedo;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章