UIBezierPath撤消绘制重绘UIImageView的图像

时间:2014-03-02 05:52:20

标签: ios objective-c uiimageview nsmutablearray uibezierpath

我正在尝试通过重绘我创建的NSMutableArray中的所有UIBezierPaths和关联的UIColors来重绘我的UIImageView图像,减去我点击撤消UIButton时的最后一条路径。

然而,在这种情况下,UIImageView的图像不会重绘并删除最后一个路径,直到NSMutableArray的计数小于2,其中它将UIImageView的图像设置为nil(这是正常工作)

我很感激提供任何帮助。注意:我没有包含我的touchesMoved方法,因为我只想让撤消'点'暂时工作。

**

更新:这是我最终使用的代码,借助下面接受的答案:

**

- (void)undoLast
{
    if (self.drawingPathArray.count < 2)
    {
        self.drawingPathArray = nil;
        self.undoButton.hidden = YES;
        self.drawingImageView.image = nil;
    }
    else
    {
        [self.drawingPathArray removeLastObject];

        self.undoButton.tintColor = [[self.drawingPathArray lastObject] objectAtIndex:0];

        UIGraphicsBeginImageContextWithOptions(self.drawingImageView.bounds.size, NO, 0.0);

        for (NSArray *subArray in self.drawingPathArray)
        {
            CGContextRef context = UIGraphicsGetCurrentContext();
            CGContextSetLineWidth(context, 3.0);
            CGContextSetLineCap(context, kCGLineCapRound);
            CGContextSetStrokeColorWithColor(context, [[subArray objectAtIndex:0] CGColor]);
            CGContextAddPath(context, [[subArray objectAtIndex:1] CGPath]);
            CGContextStrokePath(context);
        }

        self.drawingImageView.image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
}

原始问题的代码:

@property (nonatomic, strong) NSMutableArray *drawingPathArray;
@property (nonatomic, assign) NSInteger ctr;
@property (nonatomic, assign) CGPoint lastPoint;
CGPoint pts[4];

- (void)undoLast
{
    if (self.drawingPathArray.count < 2)
    {
        self.drawingPathArray = nil;
        self.undoButton.hidden = YES;
        self.drawingImageView.image = nil;
    }
    else
    {
        [self.drawingPathArray removeLastObject];

        NSArray *lastArray = [self.drawingPathArray lastObject];

        UIColor *lastColor = [lastArray objectAtIndex:0];

        self.undoButton.tintColor = lastColor;

        for (NSArray *subArray in self.drawingPathArray)
        {
            // These colors and paths are getting set correctly, verified by using NSLog
            UIColor *color = [subArray objectAtIndex:0];
            UIBezierPath *path = [subArray objectAtIndex:1];

            [self drawWithPath:path andColor:color];
        }
    }
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{           
    self.ctr = 0;
    UITouch *touch = [touches anyObject];
    pts[0] = [touch locationInView:self.drawingImageView];
}

- (void)drawWithPath:(UIBezierPath *)path andColor:(UIColor *)color
{
    path.lineWidth = 3.0;
    path.lineCapStyle = kCGLineJoinRound;

    dispatch_async(dispatch_get_main_queue(),
    ^{
        UIGraphicsBeginImageContextWithOptions(self.drawingImageView.bounds.size, NO, 0.0);

        [self.drawingImageView.image drawAtPoint:CGPointZero];
        [color setStroke];
        [path stroke];
        self.drawingImageView.image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    });
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UIBezierPath *path = [UIBezierPath bezierPath];

    if (self.ctr == 0)
    {
        [path moveToPoint:pts[0]];
        [path addLineToPoint:pts[0]];
    }

    self.undoButton.hidden = NO;
    [self.undoButton setTintColor:self.inkColor];

     if (!self.drawingPathArray)
     {
        self.drawingPathArray = [[NSMutableArray alloc]init];
     }

     [self.drawingPathArray addObject:@[self.inkColor,path]];

     [self drawWithPath:path andColor:self.inkColor];
}

1 个答案:

答案 0 :(得分:2)

在开始重绘其余路径之前,您不会清除self.drawingImageView.image。所以,你现在所做的只是重新划分旧线上的线条。

你应该做的是:

  1. 创建一个新的上下文并将所有行绘制到其中
  2. 不要将旧图像绘制到这个新的上下文中
  3. 不要使用GCD将更新排入此上下文,只需内联(如果需要,可在后台进行)
  4. 然后,最后,从上下文(image = UIGraphicsGetImageFromCurrentImageContext())获取新图像并将其保存在self.drawingImageView.image = image;


    伪代码:

    // create a new bitmap image context
    UIGraphicsBeginImageContextWithOptions(...
    ctx = UIGraphicsGetCurrentContext();
    
    for (NSArray *subArray in self.drawingPathArray) {
        // get the path and colour
        CGContextSetStrokeColor(ctx, ...
        CGContextAddPath(ctx, ... (path from bezier)
        CGContextStrokePath(ctx);
    }
    
    // create image
    image = UIGraphicsGetImageFromCurrentImageContext();
    
    self.drawingImageView.image = image;