Clear UIView of drawing?
Asked Answered
N

2

9

I am using a subclass of UIView to draw, this subclassed view is used to get your signature on a view controller. There is a clear button which is supposed to clear the UIView except it doesn't work. Here is what I have tried.

subclass.h

@implementation subclassed uiview
{
    UIBezierPath *path;
    UIImage *incrementalImage; // (1)
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [self setMultipleTouchEnabled:NO];
        [self setBackgroundColor:[UIColor clearColor]];
        path = [UIBezierPath bezierPath];
        [path setLineWidth:2.0];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    [incrementalImage drawInRect:rect]; // (3)
    [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];
    [self setNeedsDisplay];
}

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

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

- (void)drawBitmap // (3)
{
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
    //[[UIColor blackColor] setStroke];
    if (!incrementalImage) { // first draw;
        UIBezierPath *rectpath = [UIBezierPath bezierPathWithRect:self.bounds]; // enclosing bitmap by a rectangle defined by another UIBezierPath object
        [[UIColor clearColor] setFill];
        [rectpath fill]; // fill it
    }
    [incrementalImage drawAtPoint:CGPointZero];
    [path stroke];
    incrementalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}

@end

view controller.m

- (IBAction)clearTapped:(id)sender {
    self.subclassedView.backgroundColor = [UIColor clearColor];
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);
    CGContextFillRect(context,self.subclassedView.bounds);
    CGContextClearRect(context, self.subclassedView.bounds);
    CGContextFlush(context);
    [self.subclassedView setNeedsDisplay];
}

Can anyone tell me why this doesn't work, and what I should do instead?

Naquin answered 20/11, 2013 at 5:13 Comment(0)
T
16

Reinitialise the path variable and force the view to draw with this newly created empty path. This gives impression of erasing the previous drawn path. In your subclass include this function,

- (void)erase {
    path   = nil;  //Set current path nil
    path   = [UIBezierPath bezierPath]; //Create new path
    [self setNeedsDisplay]; 
}

Declare this method in the .h file of your subclass. From your view controller class you need to call this method whenever you need to erase the view,

- (IBAction)clearTapped:(id)sender {
    [self.subclassedView erase];
}

Try it out.

Hope that helps!

Tamie answered 20/11, 2013 at 5:21 Comment(2)
@JosueEspinosa This code is from a working project of mine. Can you tell me what is going wrong in your case?Tamie
I ended up actually just setting my incremental image to nil under the erase method which worked! No idea why it wasn't working with your above example though.Naquin
G
4

IT will surely work.. guaranteed... addition to answer by @Amar and comment by @Josue... thanx to you both

- (void)erase {
        path   = nil;  //Set current path nil
        path   = [UIBezierPath bezierPath]; //Create new path
        incrementalImage = nil;

        [self setNeedsDisplay];
   }
Gerhard answered 12/2, 2014 at 14:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.