这回我们来总结一下CABasicAnimation使用中的一些细节的处理问题,避免一些比较蛋疼的事情发生,显得无从下手:
- 一般的动画,我们这样写:
///开始旋转
- (void)beginRotation
{
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
anim.toValue = @(2 * M_PI);
anim.duration = 20;
anim.repeatCount = MAXFLOAT;
[self.iconView.layer addAnimation:anim forKey:nil];
}
- 确实是能转起来了,但是我们慢慢的把问题引出来,我们先包装一个导航控制器,以及点击item跳转:大概一开始是这么一个效果:
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.iconView];
[self beginRotation];
}
这个旋转动画的代码,我们放在viewDidLoad里面调,那么一运行程序是会转起来,没错。但是我们点击跳转之后,再回来这个控制器,发现就不转了,这里不绕弯子了,直接是解决办法:
anim.removedOnCompletion = NO;
只要不移除它,等一下跳转回来之后,还能继续旋转。
那么我们看一下回到后台,再进来,还是可以继续旋转的,但是我们会发现有一个跳跃的过程,因为憋太久了,所以给用户的体验,不是那么的完美,我们现在来解决一下:
那么我们就要监听应用退到后台以及前台:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
进而我们写两个方法来进行操作:
///监听应用退到后台
- (void)didEnterBackground
{
//记录暂停时间
CFTimeInterval pauseTime = [self.iconView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
//设置动画速度为0
self.iconView.layer.speed = 0;
//设置动画的偏移时间
self.iconView.layer.timeOffset = pauseTime;
}
- 前台的操作
///恢复旋转
- (void)didBecomeActive
{
//暂停的时间
CFTimeInterval pauseTime = self.iconView.layer.timeOffset;
//设置动画速度为1
self.iconView.layer.speed = 1;
//重置偏移时间
self.iconView.layer.timeOffset = 0;
//重置开始时间
self.iconView.layer.beginTime = 0;
//计算开始时间
CFTimeInterval timeSincePause = [self.iconView.layer convertTime:CACurrentMediaTime() fromLayer:nil] - pauseTime;
//设置开始时间
self.iconView.layer.beginTime = timeSincePause;
}
那么到这里,这个动画基本上也就完成了