I recently had to improve the performance of a few views that utilized CALayer-based shadows on rounded-rect UIView objects. On this particular iPad application, when the device was rotated, the views rotated quite a lot slower than we would have hoped. It wasn’t a show-stopper, but the jerky rotation animation made it look cheap and unpolished. The easiest way to have our cake, and eat it too, was to set a custom CGPath to the layer’s shadowPath property. This told UIKit to set the inside of the path to opaque, reducing the amount of work the rendering engine needed to perform.
// Add background tile UIImage *bgImage = [UIImage imageNamed:@"embedded_bg.png"]; self.view.backgroundColor = [UIColor colorWithPatternImage:bgImage]; // Add the reference view UIImage *image = [UIImage imageNamed:@"dccp.jpeg"]; UIImageView *imgView = [[UIImageView alloc] initWithImage:image]; [self.view addSubview:imgView]; imgView.center = self.view.center; imgView.layer.shadowColor = [UIColor blackColor].CGColor; imgView.layer.shadowOpacity = 0.7f; imgView.layer.shadowOffset = CGSizeMake(10.0f, 10.0f); imgView.layer.shadowRadius = 5.0f; imgView.layer.masksToBounds = NO; UIBezierPath *path = [UIBezierPath bezierPathWithRect:imgView.bounds]; imgView.layer.shadowPath = path.CGPath;
The resulting image, as you can see above, has a shadow as you’d expect. But since we’ve declared the shape the path will have, the iPad can drastically improve its rendering performance.
Through that process however, I decided to see what sort of effects I could pull off by passing in a path other than the default rectangular bounds of the layer. Since you can create any sort of path you want, I considered the different effects I could get away with by making non-rectangular paths and using them as shadows.Read More »Fun shadow effects using custom CALayer shadowPaths