2011-11-23 9 views
5

私はiOSアプリケーションにNSUndoManagerを実装しようとしています。私は元に戻す機能を持っていますが、やり直しの部分はありません。私はiOS開発には全く新しいので、NSUndoManagerを初めて使用したので、これはおそらく何か些細なことです。NSUndoManagerのやり直し機能を実装するのが難しい

私のアプリはペイント/ノートのアプリケーションです。配列の最後の10個のUIImage(私はこれが最も効率的な方法であるかどうかわかりません)を元に戻す/やり直しスタックがあります。ユーザーが現在のイメージに変更を加えると、古いイメージがスタックにプッシュされ、アレイにすでに10個のオブジェクトがある場合、アレイの最初のイメージが削除されます。配列のオブジェクトを追跡し、正しいイメージが表示されることを確認するために使用する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こんにちは、これは私にこれを手伝ってもらえますか? UIImageをアップデートするにはどうすればいいですか? –

+0

私が掲載したような元に戻すマネージャを持つメソッドは、データモデル内で使用されるはずです。これが、私が通知をポーズすることについてコメントした理由です。例:[[NSNotificationCentre defaultCentre] postNotification:XXMyDataModelDidChangeImageNotificationオブジェクト:self]。つまり、実際に画像を表示するビュー(UIImageView)を持つビューコントローラが必要です。このビュー・コントローラは、データ・モデルからの通知にサブスクライブし、通知を受信したときにビューを更新する必要があります。あるいは、KVOを使用してもよい。私はこれが役立つことを願っています – Davyd

関連する問題