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