在iOS中使用多点触控绘图撤消

时间:2014-02-21 12:54:41

标签: ios uikit nsmutablearray core-graphics undo-redo

我在写作时正在使用多点触控,所以基本上我正在做的是,我正在用手支持写作,因为通常,它是如何用户权限的,我按照这个链接How to ignore certain UITouch Points in multitouch sequence

一切都工作正常,但是当我用手触摸屏幕时,撤消它们是一个问题,否则它可以正常工作。

以下是我的代码

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch* topmostTouch = self.trackingTouch;
    for (UITouch *touch in touches)
    {
        ctr = 0;

        touchStartPoint1 = [touch locationInView:self];


        [m_undoArray removeAllObjects];
        [m_redoArray removeAllObjects];
        [m_parentRedoArray removeAllObjects];


        if(!topmostTouch || [topmostTouch locationInView:self].y > touchStartPoint1.y)
        {
            topmostTouch = touch;
            pts[0] = touchStartPoint1;
        }
    }


    if (self.trackingTouch != nil && self.trackingTouch != topmostTouch)  //              ![touches containsObject:self.trackingTouch])
    {
        [self discardDrawing];

    }

    self.trackingTouch = topmostTouch;
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{ 
    if(self.trackingTouch== nil)
    {
        return;
    }

    CGPoint p = [self.trackingTouch locationInView:self];
    ctr++;
    pts[ctr] = p;

    if (ctr == 4)
    {
        pts[3] = midPoint(pts[2], pts[4]);

        self.currentPath = [[DrawingPath alloc] init];

        [self.currentPath setPathColor:self.lineColor];
        self.currentPath.pathWidth = [NSString stringWithFormat:@"%f",self.lineWidth];


        [self.currentPath.path moveToPoint:pts[0]];
        [self.currentPath.path addCurveToPoint:pts[3] controlPoint1:pts[1] controlPoint2:pts[2]];

        CGPathRef cgPath = self.currentPath.path.CGPath;
        mutablePath = CGPathCreateMutableCopy(cgPath);

        [m_undoArray addObject:self.currentPath];
        [self setNeedsDisplay];


        pts[0] = pts[3];
        pts[1] = pts[4];
        ctr = 1;
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{    
    for (UITouch *touch in touches)
    {
        if(touch == self.trackingTouch)
        {
             [m_parentUndoArray addObject:[NSArray arrayWithArray:m_undoArray]];                
        }          
   }
}


-(void)undoButtonClicked
{     
    NSMutableArray *undoArray = [m_parentUndoArray lastObject];

    NSLog(@"%@",undoArray);

    [m_parentUndoArray removeLastObject];
    [m_parentRedoArray addObject:undoArray];
     m_drawStep = UNDO;  

    [self setNeedsDisplay];    

}


- (void)drawRect
{
   I have different cases here, I am showing Of Undo

   for(int i = 0; i<[m_parentUndoArray count];i++)
   {
       NSMutableArray *undoArray = [m_parentUndoArray objectAtIndex:i];
       NSLog(@"%@",undoArray);

      for(int i =0; i<[undoArray count];i++)
      {
         DrawingPath *drawPath = [undoArray objectAtIndex:i];
         GPathRef path = drawPath.path.CGPath;
         mutablePath = CGPathCreateMutableCopy(path);

         //Draw into CgLayer            
     }
   }
}

这是更好地理解我的问题的图像,我先写了这个

enter image description here

After clicking on undo Once

单击撤消一次后,您可以看到上面的一些其他部分已撤消,而不是最后一部分。所以在这方面我需要你的帮助。

2 个答案:

答案 0 :(得分:1)

m_redoArray似乎是大爸爸,你画的那个。我不明白为什么你在'touchesBegan ......'中把它清空了,当然这些阵列中的一个必须通过touchesBegan进行改变,或者你将从绘图的开头一直放下东西,不是吗?

在我看来,这就是你在这里放弃“地狱”的方式..

答案 1 :(得分:0)

在我的情况下,我已经使用uibezierPath进行触摸绘制并成功实现了撤消功能。这是代码:

- (id)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if (self) {
    // Initialization code

    self.backgroundColor = [UIColor clearColor];
    myPath = [[UIBezierPath alloc] init];
    myPath.lineCapStyle = kCGLineCapRound;
    myPath.miterLimit = 0;
    bSize=5;
    myPath.lineWidth = bSize;
    brushPattern = [UIColor whiteColor];

    // Arrays for saving undo-redo steps in arrays
    pathArray = [[NSMutableArray alloc] init];
    bufferArray = [[NSMutableArray alloc] init];


  }
 return self;
}

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect
{
    [brushPattern setStroke];
    for (id path in pathArray){
        if ([path isKindOfClass:[UIBezierPath class]]) {
            UIBezierPath *_path=(UIBezierPath *)path;
            [_path strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
        }
    }
}

#pragma mark - Touch Methods
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

             UITouch *mytouch = [[touches allObjects] objectAtIndex:0];
            myPath = [[UIBezierPath alloc] init];
            myPath.lineWidth = bSize;
            [myPath moveToPoint:[mytouch locationInView:self]];
            [pathArray addObject:myPath];

}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{ 
        [myPath addLineToPoint:[[touches anyObject] locationInView:self]];
        [self setNeedsDisplay];
}


#pragma mark - Undo Method
-(void)undoButtonClicked
{
    if([pathArray count]>0)
    {
    UIBezierPath *_path = [pathArray lastObject];
    [bufferArray addObject:_path];
        [pathArray removeLastObject];
        [self setNeedsDisplay];
    }

}
-(void)setBrushSize: (CGFloat)brushSize
{
    bSize=brushSize;
}

-(void)redoButtonClicked
{
    if([bufferArray count]>0){
    UIBezierPath *_path = [bufferArray lastObject];
    [pathArray addObject:_path];
    [bufferArray removeLastObject];
    [self setNeedsDisplay];
    }
}

希望它会对你有所帮助。