Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Smooth animation when animating a CALayer's shadowPath

In my app I have a UIView that is using CALayer in order to achieve a shadow:

@implementation MyUIView

    - (instancetype) initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if(!self) return self;

        self.layer.shadowColor = [UIColor colorWithWhite:0 alpha:.2].CGColor;
        self.layer.shadowOffset = CGSizeMake(0, 2);
        self.layer.shadowOpacity = 1;
        self.layer.shadowRadius = 1;

        return self;
    }

@end

If I want anything approaching reasonable performance, I have to define the CALayer's shadowPath:

@implementation MyUIView

    - (void) setFrame:(CGRect)frame {
        [super setFrame:frame];

        self.layer.shadowPath = CGPathCreateWithRect(self.bounds, NULL);
    }

@end

I've noticed two things whenever I animate this UIView:

  1. If I don't use a shadowPath, the shadow animates along nicely with rotations and frame size changes. The caveat here being very slow animation and a general lack of performance.

  2. If I do use a shadowPath whenever the UIView is animated the animation is smooth and timely, however the shadow's transition itself is much more block-like (and less smooth) than it is without a shadowPath.

Examples:

  • With shadowPath: https://gfycat.com/ColdBlissfulIndusriverdolphin (notice how the shadow behaves like a poorly transformed rectangle?)
  • Without shadowPath (the slowness of the animation is more apparent on the device, but you get the idea): https://gfycat.com/ActiveRemorsefulBandicoot

Edit:

It's worth noting that these animations are implicit - I'm not invoking them myself. They are the result of the UIViewController rotating with the device orientation. The shadow is on a UIView that changes size during rotation.

like image 772
mattsven Avatar asked Feb 28 '15 21:02

mattsven


1 Answers

I tried to reproduce the behavior shown in the two gifs you supplied, but without success (maybe you could edit your question with the animation code, e.g. UIView animateWithDuration:animations:).

However, somewhere at the back of my mind I remember that once in a while I encountered a similar issue, and it turned out that I had to rasterize the view to make it smooth.

So I cannot guarantee that it solves the problem for you, but give it a try:

self.layer.shouldRasterize = YES;
self.layer.rasterizationScale = [[UIScreen mainScreen] scale];
like image 97
Dennis Avatar answered Oct 27 '22 12:10

Dennis