[程序員日記][UIView animated]多動畫播放問題

項目需求中有這么一項,主界面中有用戶狀態(tài)(左上角)以及下面的三個列表,表中的狀態(tài)有解鎖和未解鎖兩種。要求在用戶狀態(tài)發(fā)生改變、大招及場景解鎖后回到主界面出現(xiàn)gif動畫效果。主界面如圖。


主界面

最初,通過通知判斷狀態(tài)是否發(fā)生改變,然后出現(xiàn)相應(yīng)的動畫效果。但其他界面發(fā)送解鎖的通知后,會立刻出現(xiàn)動畫效果(動畫加在 window上)。后來使用單例傳值,但其他界面改變解鎖狀態(tài),改變單例類中的相應(yīng)參數(shù),在主界面viewWillAppear中通過判斷程序中的狀態(tài)是否與單例類中的狀態(tài)是否一致,然后是否出現(xiàn)動畫。

狀態(tài)出現(xiàn)是很好判斷的,但在動畫出現(xiàn)遇到了問題。

動畫效果是界面變暗,從原位置出現(xiàn)gif動畫變大,停留3s返回原位置。我使用的是[UIView animated]block代碼塊完成。在competion中執(zhí)行返回的操作。

[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;
                                 
                                 //恢復(fù)原來的狀態(tài)
                                 _gifImageView.frame = _userStateImage.frame;
                             }completion:^(BOOL finished) {
                                 [_gifImageView removeFromSuperview];
                                 [backView removeFromSuperview];
                             }];
                         }
                     }];

但是在兩個動畫同時符合要求出現(xiàn)的時候,并沒有按照先后順序出現(xiàn),而是同時出現(xiàn),并且sleep時間出現(xiàn)了疊加。

因此 將[NSThread sleepForTimeInterval:3.0f] 改為[UIView setAnimationDelay:3.0f]延遲3s出現(xiàn)。這樣做雖然解決了時間問題,可是兩個動畫效果同時出現(xiàn) 消失,并沒有出現(xiàn)先后順序。

按照需求的優(yōu)先級,如果兩個效果同時出現(xiàn),要先出現(xiàn)解鎖的效果,然后出現(xiàn)用戶狀態(tài)發(fā)生改變的效果。

方法有更優(yōu)秀的,在這方面我處理的是用了定時器,然后在時間軸上出現(xiàn)效果。

 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];
    });
}

在動畫播放時還有一種是動畫出現(xiàn),然后用戶點擊出現(xiàn)消失動畫。若是一個那很簡單,將消失動畫寫在tapGesture點擊事件中便可以了,可是當(dāng)多個動畫出現(xiàn)時還是會有如上所說的問題。

我設(shè)了一個BOOL類型的變量用來控制是否可以點擊,但執(zhí)行第一個動畫時在點擊事件中判斷第二個是否能夠執(zhí)行,這樣便不會出現(xiàn)同一個方法執(zhí)行兩遍或者多遍的情況。

self.canTap = YES;
//當(dāng)大招解鎖
if ([DCObserveScene defaultObserveScene].actionGroup != nil) {
    //解鎖大招 通過單例類傳值
    [self observerAction:[DCObserveScene defaultObserveScene].actionGroup];
    [DCObserveScene defaultObserveScene].actionGroup = nil;
    self.canTap = NO;
}else
    //當(dāng)用戶狀態(tài)發(fā)生改變
    if (self.oldUserState != self.userStatus) {
        //對userStatus前后值進行判斷
        self.oldUserState = self.userStatus;
        [self changeUserStatusAnimation];
    }

changeUserStatusAnimation為動畫出現(xiàn)的方法,在點擊事件中,方法實現(xiàn)如下

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

    [UIView animateWithDuration:1.0f animations:^{
    
        _backView.alpha     = 0;
        _gifImageView.alpha = 0;
    
        //恢復(fù)原來的狀態(tài)
        _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;
        }
    }];
}

本著能完成需求就是好代碼的原則解決了這個問題,但是并非好的解決方法,希望能和大家多多探討。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容