这两天一直在做一个气泡动画,跟QQ里面拉圈圈那个气泡效果差不多。其实很简单,就是一个关键帧动画。
但是我这个动画的页面是在自定义的tabBarViewController上,所以当tabBar页面切换到别的页面上,再回到这个页面动画就不见了。
我在详细说一下我的情况吧。
@我的A控制器的view上添加了很多控件,其中包括我自定义的bubbleView,我给bubbleView.layer添加了一个关键帧动画,让它有那种气泡浮动效果。
@当我点击tabBar另一个按钮显示B控制器的时候,先在底下的view上将A控制器的view移除,然后再在底下的view上添加B控制器的view.
@当点击再次显示A控制器的view时,我bubbleView上的动画就不会显示了。(虽然说A 的view是重新绘制上去的,可是动画的渲染是在一个单独的线程运行的啊,我想应该是当动画的view没在显示的时候,动画会停止并移除。也没找到合适的方法检验,等后续再深入学习吧)
@bubbleView的动画不显示,这可不是我要的结果,通过查资料,又有了一种思路,就是可以让动画暂停,和恢复。给bubbleView添加了公开的暂停和恢复动画方法后,在A控制器的willAppear和willDisappear中调用暂停和恢复。可是想象总是太美好(结果跟上面一样,想一下原因,更认定view不显示的时候它上面的动画也被停止核移除了,因为我不跳页面B,页面A的view上的动画确实会暂停和恢复,所以我写的方法是没问题的)
@既然跳转页面必然A控制器的view不会显示,也就是上面的bubbleView的动画肯定会被移除,那就没啥办法了,只能再次显示页面A的时候,给bubbleView重新添加动画了。所以最后我通过纪录暂停时的时间,计算和当前时间偏移量timeoffset,重新添加动画的方法。曲线救国完成了页面跳转回来,动画依然继续的效果。
附上我的代码吧,方便以后遇到这样的问题查看
@interface MyBubbleView ()
{
CAKeyframeAnimation* animation;
CGMutablePathRef bubblepath; //动画路径
CFTimeInterval duration; //动画时间
}
@end
@implementation MyBubbleView
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0,
frame.size.width, frame.size.height)];
_imageView.userInteractionEnabled = YES;
//将⚓️设置在左上角,方便设置路径
// _imageView.layer.anchorPoint = CGPointMake(0.0, 0.0);
[self addSubview:_imageView];
}
self.backgroundColor = [UIColor clearColor];
return self;
}
- (void)setImage:(UIImage *)image
{
[_imageView setImage:image];
}
//中间气泡的路径
- (void )loadCenterPath
{
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, -4, 0);
CGPathAddLineToPoint(path, NULL, 0, -4);
CGPathAddLineToPoint(path, NULL, 4, -4);
CGPathAddLineToPoint(path, NULL, 2, 4);
CGPathAddLineToPoint(path, NULL, -2, -4);
CGPathAddLineToPoint(path, NULL, 0, 4);
CGPathCloseSubpath(path);
bubblepath = path;
duration = 12.0f;
[self startAnimation];
}
//右边气泡的路径
- (void )loadLeftPath
{
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, -4, 0);
CGPathAddLineToPoint(path, NULL, 0, 6);
CGPathAddLineToPoint(path, NULL, 4, -4);
CGPathAddLineToPoint(path, NULL, 6, 0);
CGPathAddLineToPoint(path, NULL, 4, 6);
CGPathAddLineToPoint(path, NULL, 0, 6);
CGPathAddLineToPoint(path, NULL, -2, -4);
CGPathCloseSubpath(path);
bubblepath = path;
duration = 10.0f;
[self startAnimation];
}
//左边气泡的路径
- (void )loadRightPath
{
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 4, 0);
CGPathAddLineToPoint(path, NULL, 2, -4);
CGPathAddLineToPoint(path, NULL, -6, 0);
CGPathAddLineToPoint(path, NULL, 4, 2);
CGPathAddLineToPoint(path, NULL, 0, 6);
CGPathAddLineToPoint(path, NULL, -4, -4);
CGPathAddLineToPoint(path, NULL, -6, 6);
CGPathCloseSubpath(path);
bubblepath = path;
duration = 11.0f;
[self startAnimation];
}
- (void)startAnimation
{
animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
animation.duration = duration;
animation.repeatCount = HUGE_VALF; //无穷大
animation.additive = YES; //在原来的基础上添加动画
animation.timingFunction = [CAMediaTimingFunction functionWithName:@"linear"];
animation.removedOnCompletion = YES; //移除指针
// animation.fillMode = @"forwards";
animation.path = bubblepath;
animation.timeOffset = 0.0f;
[self.imageView.layer addAnimation:animation forKey:nil];
}
//暂停动画.保存了当前位置和时间
- (void)pauseAnimation
{
CFTimeInterval pausedTime = [self.imageView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
self.imageView.layer.timeOffset = pausedTime;
}
//恢复动画
- (void)resumeLayer
{
[self.imageView.layer removeAllAnimations];
animation.timeOffset = [self.imageView.layer convertTime:CACurrentMediaTime() fromLayer:nil] - self.imageView.layer.timeOffset;
[self.imageView.layer addAnimation:animation forKey:nil];
}
@end
之前代码是在iOS 9.0上测试的通过,今天在8.1系统上不行,跳到一个页面返回来不再动画,试着改了好多次还是没办法,最后只能在页面disappear的时候将layer的动画移除,willappear的时候layer重新添加上。 想想昨天下载的app,天猫商城的个人页面的泡泡也应该是这样做的,似乎没什么好方法。
还有一个就是按了home键进入后台,返回来动画不动了,我看天猫的app也是一样会卡一下然后再动,我想可能是发了个通知,页面收到通知移除动画添加动画吧。