2

I have a UIScrollView that pretty much functions like a Facebook news feed. I thought my elements were slowing the scroll fps down. By process of elimination, I found out that the shadows slow down my app.

The UIView boxes inside the scroll view have such configuration:

self.layer.shadowColor = UIColor.blackColor().CGColor
self.layer.shadowOffset = CGSizeMake(0, 2)
self.layer.shadowRadius = 2
self.layer.shadowOpacity = 0.15

Like a news feed, my scroll view has many boxes, therefore having UIViews with their own shadows. How do I go with this without slowing down my app?

ton
  • 1,143
  • 3
  • 13
  • 34

2 Answers2

4

There's a bunch of stuff on speeding up UIScrollViews:

If you use custom CALayer instances -- especially with shadows -- stuff that requires processing power, you should use

scrollView.layer.shouldRasterize = YES;
scrollView.layer.rasterizationScale = [UIScreen mainScreen].scale;

Also a shadowPath could speed up your scrollview as well something like this:

[scrollView.layer setShadowPath:[[UIBezierPath bezierPathWithRect:myView.bounds] CGPath]];

Setting a shadowPath allows iOS to not recalculate how it should draw the shadow every time it draws the view, thus improving performance.

In swift, something like this:

let shadowPath = UIBezierPath(rect: view.bounds);
view.layer.masksToBounds = false;
view.layer.shadowColor = UIColor.blackColor().CGColor;
view.layer.shadowOffset = CGSizeMake(0, 0.5);
view.layer.shadowOpacity = 0.2;
view.layer.shadowPath = shadowPath.CGPath;
Community
  • 1
  • 1
july
  • 332
  • 1
  • 6
  • Would you say that `.shouldRasterize` and `.rasterizationScale` are enough? Could you also write a Swift equivalent for the code (especially the `setShadowPath` line)? Thanks! – ton Jun 02 '15 at 17:18
1

Setting the shadowPath will improve performance and look the same so long as your views are opaque. You could just set it to the bounds of the view or layer like so:

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

In Swift:

layer.shadowPath = CGPathCreateWithRect(bounds, nil)

The memory management is handled for you (discussed here).

stefandouganhyde
  • 4,494
  • 1
  • 16
  • 13
  • Could you write a Swift equivalent, please? Especially the line with `CGPathRelease`. Thank you! – ton Jun 02 '15 at 17:17