简体   繁体   中英

UIView subclass redraw UIBezierPath without redrawing entire view

I have an application that allows the user to draw over an image in order to eventually crop it to the path drawn. Unfortunately though it is very slow. The reason is that it relies on [self setNeedsDisplay] in order to refresh the UIBezierPath, this causes the image to redraw as well and hinders performance. Is there a way to implement this without redrawing the UIImage on every call to setNeedsDisplay ? Or a better way to implement the entire thing? All help is appreciated! Below is my UIView subclass:

#import "DrawView.h"

@implementation DrawView
{
    UIBezierPath *path;
}

- (id)initWithCoder:(NSCoder *)aDecoder // (1)
{
    if (self = [super initWithCoder:aDecoder])
    {
        [self setMultipleTouchEnabled:NO]; // (2)
        [self setBackgroundColor:[UIColor whiteColor]];
        path = [UIBezierPath bezierPath];
        [path setLineWidth:2.0];

    }
    return self;
}

- (void)drawRect:(CGRect)rect // (5)
{
    [self.EditImage drawInRect:self.bounds];
    [[UIColor blackColor] setStroke];
    [path stroke];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint p = [touch locationInView:self];
    [path moveToPoint:p];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint p = [touch locationInView:self];
    [path addLineToPoint:p]; // (4)
    [self setNeedsDisplay];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self touchesMoved:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self touchesEnded:touches withEvent:event];
}

@end

I had this issue as well in one of my apps - as you mentioned it is calling drawInRect which is causing the performance issues. The way I resolved it was by separating the background image view and the view that needs to be re-drawn multiple times into their own classes.

So in this instance you would create a class which will represent your background image and then add your "drawView" to that view with a transparent background. This way all of the drawing will be handled by drawView but the background image will remain static. Once the user is done drawing the background view can then crop itself based on the path provided by drawView.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM