[程序员日记][UIView animated]多动画播放问题

项目需求中有这么一项,主界面中有用户状态(左上角)以及下面的三个列表,表中的状态有解锁和未解锁两种。要求在用户状态发生改变、大招及场景解锁后回到主界面出现gif动画效果。主界面如图。


主界面

最初,通过通知判断状态是否发生改变,然后出现相应的动画效果。但其他界面发送解锁的通知后,会立刻出现动画效果(动画加在 window上)。后来使用单例传值,但其他界面改变解锁状态,改变单例类中的相应参数,在主界面viewWillAppear中通过判断程序中的状态是否与单例类中的状态是否一致,然后是否出现动画。

状态出现是很好判断的,但在动画出现遇到了问题。

动画效果是界面变暗,从原位置出现gif动画变大,停留3s返回原位置。我使用的是[UIView animated]block代码块完成。在competion中执行返回的操作。

[UIView animateWithDuration:1.0f
                     animations:^{
                         
                         backView.alpha = ALPHA;
                         _gifImageView.alpha = 1.0;
                         _gifImageView.frame = CGRectMake(kWIDTH/2 - gifImage.size.width/2,
                                                          kHEIGHT/2 - gifImage.size.height/2,
                                                          gifImage.size.width,
                                                          gifImage.size.height);
                     }completion:^(BOOL finished) {
                         if (finished) {
                             [UIView animateWithDuration:1.0f animations:^{

                                [NSThread sleepForTimeInterval:3.0];
                                 
                                 backView.alpha     = 0;
                                 _gifImageView.alpha = 0;
                                 
                                 //恢复原来的状态
                                 _gifImageView.frame = _userStateImage.frame;
                             }completion:^(BOOL finished) {
                                 [_gifImageView removeFromSuperview];
                                 [backView removeFromSuperview];
                             }];
                         }
                     }];

但是在两个动画同时符合要求出现的时候,并没有按照先后顺序出现,而是同时出现,并且sleep时间出现了叠加。

因此 将[NSThread sleepForTimeInterval:3.0f] 改为[UIView setAnimationDelay:3.0f]延迟3s出现。这样做虽然解决了时间问题,可是两个动画效果同时出现 消失,并没有出现先后顺序。

按照需求的优先级,如果两个效果同时出现,要先出现解锁的效果,然后出现用户状态发生改变的效果。

方法有更优秀的,在这方面我处理的是用了定时器,然后在时间轴上出现效果。

 double delayInSeconds = -5.0f;

if ([DCObserveScene defaultObserveScene].actionGroup != nil) {
    
    delayInSeconds += 5.0f;
    
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        
        //解锁大招 通过单例类传值
        [self observerAction:[DCObserveScene defaultObserveScene].actionGroup];
        [DCObserveScene defaultObserveScene].actionGroup = nil;
        
    });
}
if (self.oldUserState != self.userStatus) {
    
    delayInSeconds += 5.0f;
    
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        
        //对userStatus前后值进行判断
        self.oldUserState = self.userStatus;
        [self changeUserStatusAnimation];
    });
}

在动画播放时还有一种是动画出现,然后用户点击出现消失动画。若是一个那很简单,将消失动画写在tapGesture点击事件中便可以了,可是当多个动画出现时还是会有如上所说的问题。

我设了一个BOOL类型的变量用来控制是否可以点击,但执行第一个动画时在点击事件中判断第二个是否能够执行,这样便不会出现同一个方法执行两遍或者多遍的情况。

self.canTap = YES;
//当大招解锁
if ([DCObserveScene defaultObserveScene].actionGroup != nil) {
    //解锁大招 通过单例类传值
    [self observerAction:[DCObserveScene defaultObserveScene].actionGroup];
    [DCObserveScene defaultObserveScene].actionGroup = nil;
    self.canTap = NO;
}else
    //当用户状态发生改变
    if (self.oldUserState != self.userStatus) {
        //对userStatus前后值进行判断
        self.oldUserState = self.userStatus;
        [self changeUserStatusAnimation];
    }

changeUserStatusAnimation为动画出现的方法,在点击事件中,方法实现如下

- (void)tapGifClick:(UITapGestureRecognizer *)tap{

    [UIView animateWithDuration:1.0f animations:^{
    
        _backView.alpha     = 0;
        _gifImageView.alpha = 0;
    
        //恢复原来的状态
        _gifImageView.frame = _userStateImage.frame;
    }completion:^(BOOL finished) {
        [_gifImageView removeFromSuperview];
        [_backView removeFromSuperview];
    
        if(self.canTap == NO&&self.oldUserState != self.userStatus){
            self.oldUserState = self.userStatus;
            [self changeUserStatusAnimation];
            self.canTap = !self.canTap;
        }
    }];
}

本着能完成需求就是好代码的原则解决了这个问题,但是并非好的解决方法,希望能和大家多多探讨。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容