撤消重做问题与CGLayer [英] undo redo issues with CGLayer

查看:215
本文介绍了撤消重做问题与CGLayer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用CgLayer unod重做操作,我已经尝试了一些代码,但不能得到它的工作,不知道,我错了,下面是我的代码,我写了

I am working with unod redo operations on CgLayer, I have tried some code, but not able to get it working, dont know , where I am getting wrong, below is my code, which i have written

这是我的drawRect函数

this is my drawRect function

- (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中,然后将字典对象添加到数组中。

On touches ended , I am converting the layer into NSValue and storing as keyValue pair into NSDictionary and then adding the dictionary object to array.

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

我认为它在这里我做错了。所以朋友请帮助我。

I think its here where I am goin wrong. So friends please help me out.

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

From the comments below, I have added the function, where its draws into Cglayer(this function I am calling into 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

Regards Ranjit

推荐答案

实现撤消和重做的最好方法是实现 NSUndoManager 必须保存要撤消的每个对象的状态或重做NSUndoManager本身为您...

The best way to implement Undo and Redo is to implement NSUndoManager as a brief description of it you don't have to save each state of Object that you want to undo or redo the NSUndoManager itself make this for you ...

达到此步骤的步骤是:

1-初始化NSUndoManager。

1- Initialize NSUndoManager.

2-注册NSUndoManager对象中的对象状态,带有指定的函数调用, 。

2- Register Object state in the NSUndoManager object with specified function call will discuss this for you case later.

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

3-use undo or redo or clear actions function in NSUndoManager Object.

从我的工作解决方案

-in .h文件

@property (nonatomic,retain) NSUndoManager *undoManager;




  • in .m file

    • in .m file

      @synthesize undoManager;

      @synthesize undoManager;

      - 初始化您的NSUndoManager

      in "viewDidLoad" method -- initialize your NSUndoManager

      undoManager = [[NSUndoManager alloc] init];

      undoManager = [[NSUndoManager alloc] init];

      假设您在在你的viewDidLoad中放大/缩小的类,你将有

      Suppose that you have a function in your class that zoom in/out using pinch so in your "viewDidLoad" you will have

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

      因此,pinch会放大/缩小这样的
      注意MyImageView我们要放大/缩小

      So pinch will zoom in/out such Note that "MyImageView" is the image that we want to zoom in/out

      - (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中保存当前图像变换状态。

      -AddImage Function will save current image transformation state in NSUndoManager.

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

      所以,如果你有按钮使撤消操作

      So if you have button that make Undo action

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

      因此,如果您想取消所有操作方法

      So if you want to cancel all action you have both ways

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

      [undoManager removeAllActions];
      

      这篇关于撤消重做问题与CGLayer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆