ios如何页面来回跳转,保持动画播放并连贯

   这两天一直在做一个气泡动画,跟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,重新添加动画的方法。曲线救国完成了页面跳转回来,动画依然继续的效果。


附上结果图
ios如何页面来回跳转,保持动画播放并连贯_第1张图片


附上我的代码吧,方便以后遇到这样的问题查看

@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也是一样会卡一下然后再动,我想可能是发了个通知,页面收到通知移除动画添加动画吧。

你可能感兴趣的:(ios)