3

I tried to override the drawRect method in a simple UIView extension to draw a rectangle with rounded edges and fill it with black color, and also animate the view to resize on touch. The thing is, resizing completely deforms the drawing, as if the context remains the same for the whole time. drawRect is never called during the animation.. However, if I tell the view to draw itself after the animation it gets drawn correctly.

How can I animate the resizing without the drawing becoming deformed?

- (void)drawRect:(CGRect)rect {
  CGContextRef context = UIGraphicsGetCurrentContext();  
  CGFloat radius = rect.size.height * 0.5f;  

  CGMutablePathRef path = CGPathCreateMutable();

  CGPathMoveToPoint(path, NULL, CGRectGetMidX(rect), CGRectGetMinY(rect));
  CGPathAddArcToPoint(path, NULL, CGRectGetMaxX(rect), CGRectGetMinY(rect), 
                  CGRectGetMaxX(rect), CGRectGetMaxY(rect), radius);
  CGPathAddArcToPoint(path, NULL, CGRectGetMaxX(rect), CGRectGetMaxY(rect), 
                  CGRectGetMinX(rect), CGRectGetMaxY(rect), radius);
  CGPathAddArcToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMaxY(rect), 
                  CGRectGetMinX(rect), CGRectGetMinY(rect), radius);
  CGPathAddArcToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMinY(rect), 
                  CGRectGetMaxX(rect), CGRectGetMinY(rect), radius);
  CGPathCloseSubpath(path);

  CGContextSaveGState(context);
  CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
  CGContextAddPath(context, path);
  CGContextFillPath(context);
  CGContextRestoreGState(context);
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  [UIView animateWithDuration:1.f animations:^{
    self.frame = CGRectInset(self.frame, 0.f, -100.f);
  }];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  [UIView animateWithDuration:1.f animations:^{
    self.frame = CGRectInset(self.frame, 0.f, +100.f);
  }];
}
Avahi
  • 121
  • 1
  • 5
  • I wild guess here http://www.nomadplanet.fr/2010/11/animate-calayer-custom-properties-with-coreanimation/ – Jonny Dec 12 '12 at 12:18

1 Answers1

2

If you want rounded edge for a UIView you don't need to explicitly redefine the drawRect. There is a simpler way which consist to change the layer property of your UIView. Your view and its border will correctly be drawn during your animation.

// Make your view background color black
myView.backgroundColor = [UIColor blackColor];

// The following will allow you to change the color/border width/ corner radius of your UIView
myView.layer.borderColor  = [UIColor whiteColor].CGColor;
myView.layer.borderWidth  = kDefaultBorderWidth;
myView.layer.cornerRadius = kDefaultBorderRadius;

make sure you have include the #import <QuartzCore/QuartzCore.h> in your .m file and you have imported the QuartzCore.framework

tiguero
  • 11,477
  • 5
  • 43
  • 61
  • 1
    Agreed - and make sure you set `myView.clipsToBounds = YES;`. – Ander Aug 23 '12 at 07:18
  • Yes, but what if I want to draw some custom effects on that rounded rectangle? – Avahi Aug 23 '12 at 17:18
  • What kind of other effect you would like to achieve - my answer was related to your question... – tiguero Aug 23 '12 at 19:58
  • http://stackoverflow.com/questions/9000376/animate-a-uiviews-coregraphics-drawrect-content according to this post drawrect only work for one point in time so there is no way it will work with animation – tiguero Aug 23 '12 at 20:03