2011-11-23 3 views
5

iOS 앱에 NSUndoManager을 구현하려고합니다. 실행 취소 기능이 있지만 재실행 부분은 없습니다. 나는 iOS 개발에 상당히 익숙하다. 그리고 이것은 내가 처음으로 NSUndoManager을 사용했기 때문에 아마도 사소한 것이 될 것이다.NSUndoManager 다시 실행 기능을 구현하는 데 어려움이 있습니다.

내 앱은 페인팅/노트 찍기 앱입니다. 배열에서 가장 최근의 열 번째 인 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를 업데이트하는 방법 "UII를 업데이트하기위한 알림 게시"? –

+0

내가 게시 한 실행 취소 관리자를 사용하는 방법은 데이터 모델 내에서 사용되어야합니다. 그래서 알림을 보내는 것에 대해 의견을 말했습니다. 예를 들면 다음과 같습니다. [[NSNotificationCentre defaultCentre] postNotification : XXMyDataModelDidChangeImageNotification object : self]. 즉, 실제로 이미지를 표시하는보기 (UIImageView)가있는보기 컨트롤러가 있어야합니다. 이보기 컨트롤러는 데이터 모델의 알림에 가입하고 알림을 받으면보기를 업데이트해야합니다. 또는 KVO가 사용될 수 있습니다. 이게 도움이 되길 바란다. – Davyd