2011-11-23 63 views
5

我想在我的iOS應用程序來實現的NSUndoManager。我獲得了撤消功能,但不是重做部分。我對iOS開發很陌生,這是我第一次使用NSUndoManager,所以它可能是微不足道的。難度實施NSUndoManager重做功能

我的應用程序是一個繪畫/筆記應用程序,我有一個撤銷/重做堆棧與最後十個UIImage(我不知道這是否是最有效的方式)在一個數組中。當用戶對當前圖像進行更改時,舊圖像將被壓入堆棧,並且如果陣列中已有十個對象,則陣列中的第一個圖像將被刪除。我有,我用它來跟蹤數組中的對象,並確保正確的圖像顯示在int實例變量。我的代碼如下所示:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 

    if (oldImagesArrays.count >= 10) { 
     [oldImagesArrays removeObjectAtIndex:0]; 
    } 
    UIImage * currentImage = pageView.canvas.image; 
    if (currentImage != nil) { 
     [oldImagesArrays addObject:currentImage]; 
     undoRedoStackIndex = oldImagesArrays.count -1; 
    } 
    [...] 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 

    UIImage * currentImage = [oldImagesArrays lastObject]; 
    if (currentImage != pageView.canvas.image) { 
     [undoManager registerUndoWithTarget:self selector:@selector(resetImage) 
     object:currentImage]; 
    } 
} 

// Gets called when the undo button is clicked 
- (void)undoDrawing 
{ 
    [undoManager undo]; 
    [undoManager registerUndoWithTarget:self 
          selector:@selector(resetImage) 
          object:pageView.canvas.image]; 
    undoRedoStackIndex--; 
} 

// Gets called when the redo button is clicked 
- (void)redoDrawing 
{ 
    [undoManager redo]; 
    undoRedoStackIndex++; 
} 

- (void)resetImage 
{ 
    NSLog(@"Hello"); // This NSLog message only appears when I click undo. 
    pageView.canvas.image = [oldImagesArrays objectAtIndex:undoRedoStackIndex]; 
} 

當我點擊撤消或恢復按鈕resetImage應該被調用,並設置當前圖像到下一個或上一個對象在我的圖像堆棧(undoRedoStackIndex的電流值) ,這隻發生在我點擊撤消時,但不是重做。

解決方案& & ||更好的方法來做到這一點,將不勝感激。

+0

@JoshCaswell我增加了一些澄清我的問題。 – Anders

回答

6

你不需要保留的變化軌跡,這是撤消管理是什麼。

做一個可撤銷的方法是這樣的:

- (void)setImage:(UIImage*)image 
{ 
    if (_image != image) 
    { 
     [[_undoManager prepareWithInvocationTarget:self] setImage:_image]; // Here we let know the undo managed what image was used before 
     [_image release]; 
     _image = [image retain]; 

     // post notifications to update UI 
    } 
} 

這是它。要撤消更改,請撥打[_undoManager undo],重新撥打電話[_undoManager redo]。當您告訴撤消管理器撤消它時,會用舊圖像調用此方法。如果使用自定義按鈕撤銷操作,您可以使用[NSUndoManager canUndo]

沒有爲撤消操作的數量沒有限制驗證。如果您需要在某個時候清除撤消堆棧,請撥打removeAllActions方法。

+0

謝謝,讓它工作。懷疑它比我做得更容易。謝謝。 // Anders – Anders

+0

@Davyd嗨,你能幫我這個:) 「發佈通知更新UI」如何更新UIImage? –

+0

一個像我發佈的撤銷管理器的方法應該在數據模型中使用。這就是爲什麼我對提交通知發表評論。例如:[[NSNotificationCentre defaultCentre] postNotification:XXMyDataModelDidChangeImageNotification object:self]。這意味着應該在視圖控制器的某個地方有一個實際顯示圖像的視圖(UIImageView)。此視圖控制器應訂閱來自數據模型的通知,並在收到通知時更新視圖。或者可以使用KVO。我希望這有幫助。 – Davyd