iOS设置shadow*带来的离屏渲染
前言
在项目中,当我们想要设置View的阴影效果时,可以通过shadow*相关方法实现,如:
1 | self.layer.shadowOffset = CGSizeMake(4, -2); |
实现效果如下:
如上实现方式,有些情况下,你并不会发现有什么问题,但是一旦将其用在如UITableViewCell、UICollectionViewCell等时,你会发现,滑动时会导致大量掉帧的情况,其主要原因为,shadow*方法的使用将导致Core Animation进行离屏渲染,为了确定这一点,可以通过Instruments工具,选择Core Animation模板,选择开启Color Offscreen-Rendered Yellow Debug选项,当我们滑动CollectionView时,其帧率如下,产生了大量掉帧的情况,且正如我们所料,使用shadow*方法的视图被标黄,既使用了离屏渲染。
帧率情况如上,可以看到丢帧率很高。
解决方案
有一种很简单的方式来解决该问题,既直接向Core Animation提供阴影形状,通过调用setShadowPath来提供一个CGPath给视图的Layer,(CGPath为任意你想生成的阴影的形状),如:
1 | [myView.layer setShadowPath:[[UIBezierPath |
再次运行Instruments的Core Animation模板,能够看到,基本没有掉帧,滑动很流畅,且没有使用离屏渲染。
附录
- 当使用阴影的视图形状发生变化时,可以将阴影的设置代码放入
setFrame、layoutSubviews等方法里。 - 当对视图的
bounds进行动画时,默认其阴影是不会跟随进行动画的,但是可以通过如CAKeyframeAnimation来对其进行动画,因为我们已经知道了新旧两个CGPath。 - 能引发离屏渲染的情况除了设置
shadow,还有很多,如layer.mask、layer.shouldRasterize = YES等,当然,除了离屏渲染,还有很多影响绘图性能的问题,如Blending、Layout,等。
详细情况可参考: http://stackoverflow.com/questions/13158796/what-triggers-offscreen-rendering-blending-and-layoutsubviews-in-ios