使用核心图形进行绘图

3
我正在开发一款绘图iOS应用,现在我可以使用核心图形工具绘制线条和曲线,但是无法撤销所绘制的内容。我在绘制时保存了所有点的坐标,并尝试重复使用它们来实现撤销和恢复功能,但是没有成功。请问有谁能帮忙指出我的错误?
非常感谢任何帮助。
以下是我的代码:
   -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [tempPathArray removeAllObjects];
    UITouch *touch = [touches anyObject];

    previousPoint1 = [touch previousLocationInView:self];
    previousPoint2 = [touch previousLocationInView:self];
    currentPoint = [touch locationInView:self];

}

    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

    UITouch *touch  = [touches anyObject];

    previousPoint2  = previousPoint1;
    previousPoint1  = [touch previousLocationInView:self];
    currentPoint    = [touch locationInView:self];


    // calculate mid point
    CGPoint mid1    = midPoint(previousPoint1, previousPoint2); 
    CGPoint mid2    = midPoint(currentPoint, previousPoint1);

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
    CGPathAddQuadCurveToPoint(path, NULL, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
    CGRect bounds = CGPathGetBoundingBox(path);
    CGPathRelease(path);

    drawBox = bounds;

    //Pad our values so the bounding box respects our line width
    drawBox.origin.x        -= self.lineWidth * 2;
    drawBox.origin.y        -= self.lineWidth * 2;
    drawBox.size.width      += self.lineWidth * 4;
    drawBox.size.height     += self.lineWidth * 4;

    UIGraphicsBeginImageContext(drawBox.size);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    curImage = UIGraphicsGetImageFromCurrentImageContext();
    [curImage retain];
    UIGraphicsEndImageContext();

    [tempPathArray addObject:[NSValue valueWithCGRect:drawBox]];


    [self setNeedsDisplayInRect:drawBox];

}

    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{

    [pathArray addObject:tempPathArray];
    NSLog(@"path array count %d", [pathArray count]);
}

    - (void)drawRect:(CGRect)rect
{
    NSLog(@"draw rect");
    [curImage drawAtPoint:CGPointMake(0, 0)];
    CGPoint mid1 = midPoint(previousPoint1, previousPoint2); 
    CGPoint mid2 = midPoint(currentPoint, previousPoint1);

    context = UIGraphicsGetCurrentContext(); 

    [self.layer renderInContext:context];

    CGContextMoveToPoint(context, mid1.x, mid1.y);
    // Use QuadCurve is the key
    CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y); 

    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineWidth(context, self.lineWidth);
    CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);

    CGContextStrokePath(context);
    [super drawRect:rect];

}

    -(void)undoButtonClicked
{

    KidsPhotoBookAppDelegate *appDelegate = (KidsPhotoBookAppDelegate*)[[UIApplication sharedApplication]delegate];


    if([pathArray count]>0){
        [bufferArray addObject:[pathArray lastObject]];
        [pathArray removeLastObject];

        for (NSMutableArray *tempArray in pathArray) {
            for (int i  = 0; i < [tempArray count]; i++) {
                CGRect draw = [[tempArray objectAtIndex:i] CGRectValue];
                [self setNeedsDisplayInRect:draw];
            }
        }
    }


}
1个回答

0

试试这个:

  1. 画一条线。
  2. 再画一条线覆盖在第一条线上。
  3. 撤销。

我猜你会发现它基本上可以工作——第二条线与第一条线重叠的部分将消失,只有未重叠的部分将保留。

问题在于,你正在设置需要显示的区域是你仍然拥有的绘图部分,而不是你刚刚离开的部分。这正好是你应该做的相反的事情:你仍然拥有的部分不需要重新绘制,因为它们没有改变,而你离开的部分需要重新绘制,因为它已经改变了。

因此,在删除路径之前,设置需要显示的区域在路径的区域内。你不应该需要设置任何其他的需要显示的内容。


其实我无法理解你的理论。恐怕我无法达到你的理解水平。能否请你进一步解释一下? - Ghazanfar Ali
@GhazanfarAli:就像我说的一样,你正在设置需要在仍然存在的部分上显示,但这些部分不需要重新绘制。您需要重新绘制的区域是刚刚从中删除路径的区域。因此,只需在要删除路径的区域上设置需要显示,而不是要保留的路径区域。 - Peter Hosey
https://dev59.com/TV_Va4cB1Zd3GeqPYOyg - Abhishek Bedi
@AbhishekBedi:你在链接那个问题想表达什么? - Peter Hosey
@PeterHosey:上面链接中人们的对话解决了这个问题。没有像CGRemovePathFromContext这样的方法。 参考类似的问题:[http://lists.apple.com/archives/quartz-dev/2007/May/msg00064.html] - Abhishek Bedi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接