程序開發中我們經常會用到的兩個快捷鍵Ctrl+Z和Ctrl+C,撤銷和復制,Cocoa開發也可以實現這兩個操作,為我們提供非常簡單的操作類NSUndoManger,也可以稱之為撤銷管理器,NSUndoManger內部維護兩個棧,undo棧和redo棧。創建一個可撤銷的操作需要創建一個逆向的操作,然后通過逆向的操作達到做出對應的改變,實現起來非常簡單。
首先我們來看一個非常簡單的例子:
Message *msg=[[Message alloc]init]; [msg addObjectMethod:@"FlyElephant"]; [msg addObjectMethod:@"http://www.cnblogs.com/xiaofeixiang/"]; NSLog(@"%@",msg.mutableArr); [msg.undoManger undo];//取消 NSLog(@"%@",msg.mutableArr); [msg.undoManger redo];//重做 NSLog(@"%@",msg.mutableArr);
Message類中可變數組屬性mutaleArr,先來觀察一下結果,可以思考一下是如何實現的:
數組初始化元素為init,之后我們新增兩個新元素,這個時候通過undo取消了新加入的元素,之后我們通過redo將刪除的元素又重新加入到了數組中;
-(void)addObjectMethod:(NSString *)str{ [[self.undoManger prepareWithInvocationTarget:self] removeObjectMethod:str];//逆向刪除 [self.mutableArr addObject:str]; } -(void)removeObjectMethod:(NSString *)str{ [[self.undoManger prepareWithInvocationTarget:self] addObjectMethod:str];//逆向添加 if ([self.mutableArr containsObject:str]) { [self.mutableArr removeObject:str]; } }
如果細心會發現我們在兩個對應的方法中都加入了對應的逆向操作,如果你只需要取消,那么在removeObjectMethod方法中,不需要進行逆向操作,當然使用redo方法時也就不能執行,具體可以根據的需求而定;
撤銷管理器記錄的操作有三個方法:
- (id)prepareWithInvocationTarget:(id)target; - (void)registerUndoWithTarget:(id)target selector:(SEL)selector object:(nullable id)anObject; - (void)registerUndoWithTarget:(id)target handler:(void (^)(id target))undoHandler NS_AVAILABLE(10_11, 9_0) NS_REFINED_FOR_SWIFT;
prepareWithInvocationTarget是我們使用的,當然你可以通過registerUndoWithTarget:(id)target selector:(SEL)selector object:(nullable id)anObject來使用,registerUndoWithTarget:hanlder通過block的形式進行傳遞修改, 不過需要在iOS9中才可以使用,使用的時候避免造成保留環~