撤销CGLayer的重做问题

我正在与CgLayer上的unodo重做操作,我已经尝试了一些代码,但不能够得到它的工作,不知道,我在哪里出错,下面是我的代码,我已经写

这是我的drawRect函数

- (void)drawRect:(CGRect)rect { m_backgroundImage = [UIImage imageNamed:@"bridge.jpg"]; CGPoint drawingTargetPoint = CGPointMake(0,0); [m_backgroundImage drawAtPoint:drawingTargetPoint]; switch(drawStep) { case DRAW: { CGContextRef context = UIGraphicsGetCurrentContext(); if(myLayerRef == nil) { myLayerRef = CGLayerCreateWithContext(context, self.bounds.size, NULL); } CGContextDrawLayerAtPoint(context, CGPointZero, myLayerRef); break; } case UNDO: { [curImage drawInRect:self.bounds]; break; } default: break; } } 

在触摸结束时,我将图层转换为NSValue并存储为keyValue对NSDictionary,然后将字典对象添加到数组。

 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { NSValue *layerCopy = [NSValue valueWithPointer:myLayerRef]; NSDictionary *lineInfo = [NSDictionary dictionaryWithObjectsAndKeys:layerCopy, @"IMAGE", nil]; [m_pathArray addObject:lineInfo]; NSLog(@"%i",[m_pathArray count]); } 

下面是我的撤消function

 - (void)undoButtonClicked { if([m_pathArray count]>0) { NSMutableArray *_line=[m_pathArray lastObject]; [m_bufferArray addObject:[_line copy]]; [m_pathArray removeLastObject]; drawStep = UNDO; [self redrawLine]; } } //Redraw functions - (void)redrawLine { NSDictionary *lineInfo = [m_pathArray lastObject]; NSValue *val = [lineInfo valueForKey:@"IMAGE"]; CGLayerRef layerToShow = (CGLayerRef) [val pointerValue]; CGContextRef context1 = CGLayerGetContext(layerToShow); CGContextDrawLayerAtPoint(context1, CGPointMake(00, 00),layerToShow); [self setNeedsDisplayInRect:self.bounds]; } 

我想在这里我错了。 所以朋友请帮助我。

从下面的评论,我已经添加了function,其中绘制到Cglayer(这个函数我调用touchesMovedEvent。

 - (void) drawingOperations { CGContextRef context1 = CGLayerGetContext(myLayerRef); CGPoint mid1 = midPoint(m_previousPoint1, m_previousPoint2); CGPoint mid2 = midPoint(m_currentPoint, m_previousPoint1); CGContextMoveToPoint(context1, mid1.x, mid1.y); CGContextAddQuadCurveToPoint(context1, m_previousPoint1.x, m_previousPoint1.y, mid2.x, mid2.y); CGContextSetLineCap(context1, kCGLineCapRound); CGContextSetLineWidth(context1, self.lineWidth); CGContextSetStrokeColorWithColor(context1, self.lineColor.CGColor); CGContextSetAllowsAntialiasing(context1, YES); CGContextSetInterpolationQuality(context1, kCGInterpolationHigh); CGContextSetAlpha(context1, self.lineAlpha); CGContextStrokePath(context1); } 

关心Ranjit

实现Undo和Redo的最好方法是实现NSUndoManager作为它的简要描述,你不必保存每个你想撤销或重做NSUndoManager本身的对象的状态。

达到这个目标的步骤是:

1-初始化NSUndoManager。

2-注册具有指定函数调用的NSUndoManager对象中的对象状态将在稍后讨论。

在NSUndoManager对象中使用3次撤消或重做或清除操作function。

从我的工作解决scheme

在.h文件中

 @property (nonatomic,retain) NSUndoManager *undoManager; 
  • 在.m文件中

    @synthesize撤销pipe理器;

  • 在“viewDidLoad”方法 – 初始化您的NSUndoManager

    undoManager = [[NSUndoManager alloc] init];

假设你有一个在你的“viewDidLoad”你将有捏放大/缩小的function

 UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)]; pinchGesture.delegate = (id)self; [self.view addGestureRecognizer:pinchGesture]; 

所以捏会放大/缩小这样的注意,“MyImageView”是我们想要放大/缩小的图像

 - (void)pinch:(UIPinchGestureRecognizer*)recognizer{ if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateChanged) { NSLog(@"gesture.scale = %f", recognizer.scale); CGFloat currentScale = self.MyImageView.frame.size.width / self.MyImageView.bounds.size.width; CGFloat newScale = currentScale * recognizer.scale; //Here is the line that register image to NSUndoManager before making and adjustments to the image "save current image before changing the transformation" //Add image function is function that fired when you Make undo action using NSUndoManager "and so we maintain only image transformation that changed when you zoom in/out" [[undoManager prepareWithInvocationTarget:self] AddImage:self.MyImageView.transform]; if (newScale < 0.5) { newScale = 0.5; } if (newScale > 5) { newScale = 5; } CGAffineTransform transform = CGAffineTransformMakeScale(newScale, newScale); self.MyImageView.transform = transform; recognizer.scale = 1; } } 

-AddImage函数会将当前的图像转换状态保存在NSUndoManager中。

 -(void)AddImage:(CGAffineTransform)sender{ CGAffineTransform transform = sender; self.MyImageView.transform = transform; } 

所以,如果你有button,使撤消行动

 -(IBAction)OptionsBtn:(id)sender{ if ([undoManager canUndo]) { [undoManager undo]; } } 

所以如果你想取消所有的行动,你有两种方式

 while ([undoManager canUndo]) { [undoManager undo]; } 

要么

 [undoManager removeAllActions]; 
  • (void)redrawLine {NSDictionary * lineInfo = [m_pathArray lastObject];

    NSValue * val = [lineInfo valueForKey:@“IMAGE”];

    CGContextRef context1 =(CGContextRef)[val pointerValue]; CGContextDrawLayerAtPoint(context1,CGPointMake(00,00),layerToShow); [self setNeedsDisplayInRect:self.bounds]; }

只需用你的代码更新这个方法