2

NSUndoManager を使用して元に戻す/やり直しメソッドを実装しようとしています。これについて他の質問をしましたが、まだ行き詰まっています。

現時点で私がいる場所は次のとおりです。

.h
NSUndoManager *undoManager;
@property(nonatomic,retain) NSUndoManager *undoManager;

.m
@synthesize undoManager;

[undoManager setLevelsOfUndo:99]; viewdidload:

NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];      
[dnc addObserver:self selector:@selector(undoButtonTapped) name:@"undo" object:nil];   
[dnc addObserver:self selector:@selector(redoButtonTapped) name:@"redo" object:nil];

- (void)resetTheImage:(UIImage*)image
{
    NSLog(@"%s", __FUNCTION__);

   // image = savedImage.image;
    if (image != drawImage.image)
    {
        [[undoManager prepareWithInvocationTarget:self] resetTheImage];
        image = drawImage.image ;        
    } else {
        NSLog(@"That didn't work");
    }
}

- (void)undoButtonTapped {
    NSLog(@"%s", __FUNCTION__);
    [undoManager undo];
}

「それはうまくいきませんでした」と出ます...

助けていただければ幸いです。何が間違っているのかがわかったら、元の質問への回答を投稿します。

- -編集 - -

次のように resetTheImage を変更しました。

- (void)resetTheImage:(UIImage*)image
{
    NSLog(@"%s", __FUNCTION__);

    image = savedImage.image;
    if (image != drawImage.image)
    {
        drawImage.image = image;
        savedImage.image = image;
        NSLog(@"undo image");
        [[self.undoManager prepareWithInvocationTarget:drawImage.image] image];        

    } else {
        NSLog(@"same image");
        savedImage.image = image;
    }
}

しかし、混乱が降りかかります - 誰か (Brad?, Justin?) が、これを機能させるために必要な手順の箇条書きリストを提供してくれると助かります。例えば:

. ... に通知を追加します。トリガー通知.... 元に戻す/やり直しボタンが... を指すようにします。私が本当に構築する必要があるメソッド/関数は何ですか... ....

SOがあなたに1より多くのポイントを与えることを許可してくれることを願っています..

(私の「o」キーがぐらつくのは助けにはなりません) 昨日孫娘が生まれたのは助けになります:)))

4

1 に答える 1

1

まず、すべての支援に感謝します。これが最善の解決策かどうかはわかりませんが、最終的にこれを解決しました。

UIViewController から呼び出される UIView を作成しました。コントロール (色とブラシ) は VC に残ります。描画メソッドは View メソッドに移動します。

View メソッドは Drawing メソッドを呼び出して実際に描画を実行し、View メソッドは元に戻す/やり直しを制御します。

以下にいくつかのコード スニペットを示します。

-(void)undoButtonClicked
{
    //NSLog(@"%s", __FUNCTION__);
    if ([self.currentArray count] == 0) {
        //nothing to undo
        return;
    }

    DrawingPath *undonePath = [self.currentArray lastObject];
    [self.currentArray removeLastObject];
    [self.redoStack addObject:undonePath];
    [self setNeedsDisplay];

}

-(void)redoButtonClicked
{
    //NSLog(@"%s", __FUNCTION__);

    if ([self.redoStack count] == 0) {
        // nothing to redo
        return;
    }

    DrawingPath *redonePath = [self.redoStack lastObject];
    [self.redoStack removeLastObject];
    [self.currentArray addObject:redonePath];
    [self setNeedsDisplay];

}

誰かが明確にしたい場合はお知らせください。ありがとうございました。

要求に応じて更新:

これらはいくつかのヘッダーです:

    DrawingViewController  *mvc;
    NSMutableArray *pathArray;
    NSMutableArray *colorArray;
    NSMutableArray *bufferArray;
    NSMutableArray *currentArray;
    UIBezierPath *myPath;
    NSString *brushSize;
    CGPoint lastPoint;
    int colorIndex;
    NSString *colorKey;

    SoundEffect         *erasingSound;
    SoundEffect         *selectSound;

    BOOL swiped;    
    int moved;
    UIColor *currentColor;
    NSString *result;
}
@property(nonatomic,assign) NSInteger undoSteps;
@property (strong, nonatomic) NSString *result;

@property (strong,nonatomic) UIColor *currentColor;
@property (strong,nonatomic) NSMutableArray *currentArray;
@property (strong,nonatomic) NSMutableArray *bufferArray;
@property (strong,nonatomic) DrawingPath *currentColoredPath;
@property (strong,nonatomic) NSMutableArray *redoStack;
@property (strong, nonatomic) NSString *colorKey;

ここにいくつかのメソッドがあります.. currentArray は、ポイント、ブラシ、および色を一種のスタックで追跡します。元に戻すは、スタックから削除し、やり直しに使用できる一時スタックに追加します。

-(void)undoButtonClicked
{
    //NSLog(@"%s", __FUNCTION__);
    if ([self.currentArray count] == 0) {
        //nothing to undo
        return;
    }

    DrawingPath *undonePath = [self.currentArray lastObject];
    [self.currentArray removeLastObject];
    [self.redoStack addObject:undonePath];
    [self setNeedsDisplay];

}

-(void)redoButtonClicked
{
    //NSLog(@"%s", __FUNCTION__);

    if ([self.redoStack count] == 0) {
        // nothing to redo
        return;
    }

    DrawingPath *redonePath = [self.redoStack lastObject];
    [self.redoStack removeLastObject];
    [self.currentArray addObject:redonePath];
    [self setNeedsDisplay];

}


#pragma mark - Touch Methods
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{   
    //NSLog(@"%s", __FUNCTION__);
    self.currentColoredPath = [[DrawingPath alloc] init];
    [self.currentColoredPath setColor:self.currentColor];
    UITouch *touch= [touches anyObject];


    [self.currentColoredPath.path moveToPoint:[touch locationInView:self]];
    [self.currentArray addObject:self.currentColoredPath];
    // Remove all paths from redo stack
    [self.redoStack removeAllObjects];

    lastPoint = [touch locationInView:self];
    lastPoint.y -= 20;

    if ([touch tapCount] == 2) {
        [self alertOKCancelAction];

        return;
    }  


}



-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    //NSLog(@"%s", __FUNCTION__);
    UITouch *touch = [touches anyObject]; 
    [self.currentColoredPath.path addLineToPoint:[touch locationInView:self]];

    [self setNeedsDisplay];


    CGPoint currentPoint = [touch locationInView:self];
    currentPoint.y -= 20;


    lastPoint = currentPoint;

}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    //NSLog(@"%s", __FUNCTION__);
    self.currentColoredPath = nil;
}
于 2012-04-21T17:08:20.757 に答える