我正在CgLayer上执行unod redo操作,我已经尝试了一些代码,但是无法使其正常工作,不知道,我哪里出错了,下面是我编写的代码

这是我的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]);

}


以下是我的撤消功能

- (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];
}


我认为这里是我犯错的地方。所以朋友请帮帮我。

从下面的注释中,我添加了该函数,该函数将其绘制到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);
}


问候
兰吉特

最佳答案

实现撤消和重做的最好方法是实现NSUndoManager作为它的简短描述,您不必保存要撤消或重做的Object的每种状态,NSUndoManager本身就为您提供了...

达到此目的的步骤是:

1-初始化NSUndoManager。

2-使用指定的函数调用在NSUndoManager对象中注册对象状态将在以后为您讨论。

3在NSUndoManager对象中使用撤消,重做或清除操作功能。

从我的工作解决方案

-in .h文件

@property (nonatomic,retain) NSUndoManager *undoManager;



在.m文件中

@synthesize undoManager;
在“ viewDidLoad”方法中-初始化您的NSUndoManager

undoManager = [[NSUndoManager alloc] init];


假设您的班级中有一个使用捏放大/缩小的函数,因此在“ viewDidLoad”中

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;
}


因此,如果您有执行撤消操作的按钮

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


因此,如果您想取消所有操作,则有两种方式

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


要么

[undoManager removeAllActions];

10-08 07:43