美文网首页iOS && AndroidiOS进阶指南iOS开发技术分享
[程序员日记][UIView animated]多动画播放问题

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

作者: KeyLiu7 | 来源:发表于2016-05-03 13:04 被阅读178次

    项目需求中有这么一项,主界面中有用户状态(左上角)以及下面的三个列表,表中的状态有解锁和未解锁两种。要求在用户状态发生改变、大招及场景解锁后回到主界面出现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;
            }
        }];
    }
    

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

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/yoolrttx.html