Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIView draw rect retain's the previous drawing and does not clear on view.transform

I have the following code to show marker in a UIView. The marker show's well, and once we try to pinch zoom and scale the UIView using the transform the first drawing remains as it is, even after calling setNeedsDisplay.

My Custom UIView subclass has the following code

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    CGFloat w=20.0f;
    CGFloat h=8.0f;


    CGContextRef context=UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
    CGContextClearRect(context,self.bounds);

    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
    CGContextSetLineCap(context, 2.0);


    CGMutablePathRef leftMarker=CGPathCreateMutable();
    CGPathMoveToPoint(leftMarker, NULL, 0, 0);
    CGPathAddLineToPoint(leftMarker, NULL, w, 0);
    CGPathAddLineToPoint(leftMarker,NULL, w, h);
    CGPathAddLineToPoint(leftMarker,NULL, h, h);
    CGPathAddLineToPoint(leftMarker,NULL,h, w);
    CGPathAddLineToPoint(leftMarker,NULL,0, w);
    CGPathAddLineToPoint(leftMarker,NULL, 0, 0);

    CGContextAddPath(context, leftMarker);

    CGContextDrawPath(context, kCGPathFill);
    const CGAffineTransform rightMarkerTransform=CGAffineTransformMakeRotateTranslate(DEGREES_TO_RADIANS(90),self.frame.size.width,0);

    CGPathRef rightMarker=CGPathCreateCopyByTransformingPath(path, &rightMarkerTransform);
    CGContextAddPath(context, rightMarker);
    CGContextDrawPath(context, kCGPathFill);
    const CGAffineTransform leftMarkerBottomTransform=CGAffineTransformMakeRotateTranslate(DEGREES_TO_RADIANS(270),0,self.frame.size.height);

    CGPathRef leftMarkerbottom=CGPathCreateCopyByTransformingPath(path, &leftMarkerBottomTransform);
    CGContextAddPath(context, leftMarkerbottom);
    CGContextDrawPath(context, kCGPathFill);

    const CGAffineTransform rightMarkerBottomTransform=CGAffineTransformMakeRotateTranslate(DEGREES_TO_RADIANS(180),self.frame.size.width,self.frame.size.height);

    CGPathRef rightMarkerBottom=CGPathCreateCopyByTransformingPath(path, &rightMarkerBottomTransform);
    CGContextAddPath(context, rightMarkerBottom);
    CGContextDrawPath(context, kCGPathFill);

    CGPathRelease(rightMarker);
    CGPathRelease(leftMarkerbottom);
    CGPathRelease(rightMarkerBottom);
    CGPathRelease(leftMarker);
}

The pinch zoom code is listed below

CGFloat lastScale;
-(void) handlepinchGesture:(UIPinchGestureRecognizer*)gesture{
    UIView *gestureV=gesture.view;
    CGFloat scale=gesture.scale;
    switch (gesture.state) {
        case UIGestureRecognizerStateBegan:
            if(lastScale<1.0){
            lastScale=1.0;
            }
            scale=lastScale;
            break;
        default:
            break;
    }

    if(scale<1.0){
        scale=1.0;
    }
    lastScale=scale;
    gestureV.transform=CGAffineTransformMakeScale(scale, scale);
    //Even this does not work ….[gestureV setNeedsDisplay];
    gesture.scale=scale;
}
like image 430
NNikN Avatar asked Aug 18 '14 09:08

NNikN


1 Answers

Make you sure have this set (but it should be defaulted to YES).

self.clearsContextBeforeDrawing = YES;

From Apple's Docs in UIView

When set to YES, the drawing buffer is automatically cleared to transparent black before the drawRect: method is called. This behavior ensures that there are no visual artifacts left over when the view’s contents are redrawn. If the view’s opaque property is also set to YES, the backgroundColor property of the view must not be nil or drawing errors may occur. The default value of this property is YES.

If you set the value of this property to NO, you are responsible for ensuring the contents of the view are drawn properly in your drawRect: method. If your drawing code is already heavily optimized, setting this property is NO can improve performance, especially during scrolling when only a portion of the view might need to be redrawn.

like image 138
DBD Avatar answered Oct 05 '22 06:10

DBD