UIBezierPath 撤消绘图重绘 UIImageView 的图像

2024-04-03

我试图通过重绘我创建的 NSMutableArray 中的所有 UIBezierPath 和关联的 UIColor 来重绘 UIImageView 的图像,减去点击撤消 UIButton 时的最后一个路径。

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

我将不胜感激提供的任何帮助。注意:我不包括 TouchMoved 方法,因为我现在只想撤消“点”。

**

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

**

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

你不清楚self.drawingImageView.image在开始重绘剩余路径之前。因此,您当前所做的就是在旧线上重新绘制线条。

你应该做的是:

  1. 创建一个新上下文并将所有线条绘制到其中
  2. 不要将旧图像绘制到这个新上下文中
  3. 不要使用 GCD 对此上下文的更新进行排队,只需内联执行(如果需要,可以在后台执行)

然后,最后从上下文中获取新图像(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;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UIBezierPath 撤消绘图重绘 UIImageView 的图像 的相关文章

随机推荐