제 페인트 응용 프로그램에서 실행 취소 기능을 구현했습니다. 아이디어는 실행 취소가 저장된 레이어 배열에서 그리도록 레이어를 설정한다는 것입니다. 이 메서드는 뷰를 드로잉하기 전에 바로 호출됩니다. layerArray는 C 배열입니다. 사용자가 실행 취소하면실행 취소하면보기가 완전히 지워집니다.
-(void)updateLayerUndo
{
CGLayerRef undoLayer = CGLayerCreateWithContext([self.theCanvas viewContext], self.theCanvas.bounds.size, nil);
layerArray[undoCount] = undoLayer;
undoCount += 1;
[[self.undoer prepareWithInvocationTarget:self]performUndoOrRedoWithValueForLayer:layerArray[undoCount - 1]];
}
, 그것은 자연적으로 등록 된 메서드를 호출
-(void)performUndoOrRedoWithValueForLayer:(CGLayerRef)aLayer
{
undoCount -= 1;
self.theCanvas.myLayer = aLayer;
[[NSNotificationCenter defaultCenter]postNotificationName:@"UndoOrRedoPerformed" object:nil];
[self.theCanvas setNeedsDisplay:YES];
}
뷰는 다음 정말 뷰의 맥락에서 myLayer을 그립니다의 그리기 방법을 수행합니다. 그러나 사용자가 실행 취소하면보기가 증분 대신 완전히 지워집니다. 나는 뭔가를 놓치고있는 것처럼 느껴지거나 NSUndoManager를 이해하지 못할 수도 있습니다. 아, 그리고 내가 위에서 보여준 메소드는 둘 다 NSDocument 서브 클래스에 있고 theCanvas는 NSView 서브 클래스의 인스턴스입니다.
왜 'NSDocument'의'self.undoManager' 대신에'self.undoer'를 사용하고 있습니까? OSX는 이벤트 루프를 기반으로'beginUndoGrouping' /'endUndoGrouping'을 자동으로 처리합니다. 이것은 그룹이 올바르게 생성된다는 것을 의미합니다. 별도로 관리되는 NSUndoManager를 사용하고 있다면, 적절한 그룹 관리를 얻지 못할 수도 있습니다 (단,'windowWillReturnUndoManager :'에서'self.undoer'를 반환하지 않는 한). 실행 취소 할 때 반대 작업을 등록한 것처럼 보이지 않기 때문에 재실행 등록에 문제가있을 수도 있습니다. – gaige
아, NSDocument 클래스에 실행 취소 관리자가 이미 있다는 것을 알지 못했습니다. 나는 네가 하나를 창조 할 책임이 있다고 생각했다. 나는 그것을 들여다 볼 것이다! – PopKernel
그래, 그게 효과가 없었어 ... 반대편을 등록하지 않는 이유는 무엇입니까? 이전 레이어를 배열에 저장하고 액세스하는 것으로 충분하다고 생각했습니다. – PopKernel