Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force redraw of a UIView or CALayer on scale/transform

Say you have a UIView or a CALayer that does its own (vector) drawing, and you want it to remain crisp at any size, even when scaling the view or layer. How can I make it redraw when it is scaled with the transform property? Is the only way to do to force a bounds change instead of using the transform? Or to call setNeedsDisplay at every step?

Why do UIImageView seem to behave differently (i.e. it seems to always scale its source image appropriately, even when it is scaled with transform and the bounds doesn't change)? Is it because it's the only case where the content property of the underlying CALayer is set directly?

like image 282
Guillaume Avatar asked Feb 16 '23 11:02

Guillaume


2 Answers

if needsDisplayOnBoundsChange on the CALayer is not enough in your case, you can subclass CALayer and implement the + (BOOL)needsDisplayForKey:(NSString *)key method. Example:

+ (BOOL)needsDisplayForKey:(NSString *)key {
    if ([key isEqualToString:@"transform"]) {
        return YES;
    }
    return [super needsDisplayForKey:key];
}

now your layer should be redrawn everytime the transform property changes. This might cause performance issues in animations if your drawing is extensive.

like image 59
Jonathan Cichon Avatar answered Mar 06 '23 04:03

Jonathan Cichon


For vector based layers, you can use CAShapeLayer. This specalised layer takes a path and will redraw as needed to keep the layer looking crisp.

Create a CGPathRef and assign it to the layer's path:

shapeLayer.path = myPath;
like image 36
Graham Miln Avatar answered Mar 06 '23 04:03

Graham Miln