Question

I am capturing the contents of a UIView into a UIImage using view.layer renderInContext:UIGraphicsGetCurrentContext(). The view is UICollectionView and I have added shadows to each cell in the following way:

cell.layer.masksToBounds = NO;
cell.layer.shadowOpacity = 0.75f;
cell.layer.shadowRadius = 3.0f;
cell.layer.shadowOffset = CGSizeZero;
cell.layer.shadowPath = [UIBezierPath bezierPathWithRect:cell.bounds].CGPath;
cell.layer.shouldRasterize = YES;

Conversion to UIImage goes as follows:

UIGraphicsBeginImageContextWithOptions(view.frame.size, 0, 0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

The trouble is that while the the initial display of the cells seems fast enough, when I capture the snapshot of the view, the addition of the shadows slows down the performance by 10-30 times, depending on the shadow radius. On an iPad 2, it goes from 70 ms with no shadows, to full 2 seconds with 3px shadows!

I have read that setting layer.shadowPath should help with performance, but I actually do not see any appreciable difference in speed whether it is set or not.

What can I do to speed up the rendering on the snapshot in this case? The cells are not guaranteed to be any specific size so unfortunately I cannot use a pre-rendered image to fake a shadow effect.

Was it helpful?

Solution

renderInContext: is slow. That is why iOS 7 adds the UIView snapshotting methods (such as snapshotViewAfterScreenUpdates:). Use them where possible; they are much faster.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top