一. 背景
最近做项目的时候遇到一个问题,就是UITableViewCell
的UIImageView
加载gif
图有时候可以正常显示动画效果,有时候不显示动画效果。基于这个问题,做了一下分析,找到原因并记录一些。
二. 问题定位
经过调试定位,发现问题的原因在于,项目里面UITableViewCell
的UIImageView
加载gif
图,是单独拿出来,获取到图片数据之后,单独设置,而不是直接在UITableViewCell
生成之后去设置的。
就类似如下场景:
加载逻辑.png因此当imageView
去加载gif
图之后,然后UITableView
调用reloadData
方法,这时imageView
加载的gif
的动画效果就不显示,而是展示静态图.
具体表现如下:
cellImageLoad.gif因此问题的本质原因就在于UITableView
的reloadData
里面做了什么操作,将UIImageView
的图片的动画效图移除了。
三. 原因解析
A. UIImageView
的动效形式
- 首先我们必须确定下,
UIImageView
加载gif
动效图,这里动画效果,是一个CAAnimation
动效,还是UIImageView内部通过 CADisplayLink
定时器实时获取animationImages
数组的图片来更新的。 - 针对这个问题,我们可以通过如下方式验证,就是我们让
UIImageView
加载gif
动效图,然后在主线程执行耗时的操作,看图片的动画是否依然执行,如果依然执行,就说明这是一个CAAnimation
动效,动画效果是由Core Animation
来生成的,而不是通过定时器实时更新,如果图片不展示动画效果,则说明UIImageView
展示动画效果,是通过定时器实时刷新来实现的。
这里我们先将会移除动画效果的[self.tableView reloadData];
注释掉,然后在tableView
的点击方法里,加一个休眠5
s的逻辑.
我们可以发现,即使在主线程休眠了5s
或者执行其他耗时的操作,图片的动画效果依然继续执行,就可以证明UIImageView
的动画是一个CAAnimation
动效。
B. UITableView
的reloadData
是否移除`CAAnimation动效
image
我们在FJFSecondAnimationCell
的testButton
添加一个摇晃的CAKeyframeAnimation
动画,然后在监听动画的start
和stop
方法,判断UITableView
调用reloadData
方法后,发生了什么。
从日志输出中我们可以很容易的看出,UITableView
调用reloadData
方法后,testButton
的动画被移除了,执行了动画的stop
代理方法。
四. 总结
经过以上的分析,我们可以得出结论,UIImageView
加载的动效图,在UITableView
上会偶然不显示的原因是:
-
UIImageView
加载的gif
动效或者UIImageView
的animationImages
动画效果,是一个CAAnimation
的动画效果 - 在
UITableView
调用reloadData
方法后,会将UITableView
内部的UITableViewCell
的子视图移除动画效果,进行重置,这样有利于UITableViewCell
的复用。
五. 解决方法
- 如果要规避
UIImageView
加载的动效图,在UITableView
上会偶然不显示的问题,最好就是将图片的加载的方法,放在UITableViewCell
生成的代理方法中,这就相当于在UITableView
调用reloadData
方法后,会将UITableView
内部的UITableViewCell
的子视图移除动画效果之后,重新加载动画。
网友评论