簡體   English   中英

UIView動畫在iOS 7中不起作用

[英]UIView animation not working in iOS 7

我正在一個示例項目中,其中有一個垂直scrollview和一個水平scrollview 垂直scrollview視圖具有許多子視圖。 scrollviewDidScroll我正在執行一些操作。 與此相關的是,我現在想在屏幕上可見該特定子視圖時在垂直滾動視圖中為該子視圖設置動畫。 為此,我正在做一個正確的計算。 動畫如下:

子視圖包含多個自定義視圖。 我正在嘗試以某個特定的時間順序對每個視圖進行動畫處理(減小然后再增加該視圖的Alpha值)(以便動畫看起來是按順序的)。 為此,我將通知發布到視圖,並且動畫序列和邏輯根據我想要的是完美的。

但是我遇到了一個問題,當我放置斷點時,代碼正在執行,但是動畫沒有顯示。 如果我在停止滾動后發布通知,則動畫會非常好。 但是我希望動畫即使在滾動並且視圖在屏幕上時也能發生。

我正在添加我的代碼片段,如下所示:

SubView :(在我的scrollview

- (void)animateSequenceTemplate {
if (!hasSequenceTemplateAnimated) {
    [self performSelector:@selector(animateSequenceSlides) withObject:nil afterDelay:0];
    hasSequenceTemplateAnimated = YES;
}
else {
    return;
}
}

- (void)animateSequenceSlides {
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:imageAsset forKey:@"assetMO"];
[[NSNotificationCenter defaultCenter]postNotificationName:AnimateSequenceSlide object:nil userInfo:userInfo];
}

上面的子視圖中的子視圖:

- (void)animateSlideView:(NSNotification *)notification {

NSDictionary *userInfo = notification.userInfo;
if ([userInfo objectForKey:@"assetMO"] == assetMO) {
    [[NSNotificationCenter defaultCenter]removeObserver:self name:AnimateSequenceSlide object:nil];

    CGFloat duration = 0.035;
    float delay = (self.slideCount * duration);
    CGFloat timeDelay = 0;


    [self performSelector:@selector(animationPhase1) withObject:nil afterDelay:delay];
    timeDelay = delay + duration;
    [self performSelector:@selector(animationPhase2) withObject:nil afterDelay:timeDelay];

    if (self.slideCount == (self.maxSlideCount - 1)) {
        timeDelay += duration * 18; //No animation till 18 frames
    }
    else {
        timeDelay += duration;
    }
    [self performSelector:@selector(animationPhase3) withObject:nil afterDelay:timeDelay];
    timeDelay += duration;
    [self performSelector:@selector(animationPhase4) withObject:nil afterDelay:timeDelay];
}
}

- (void)animationPhase1 {
[UIView animateWithDuration:0.035 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^ {
    [self setAlpha:0.85];
}completion:^(BOOL finished) {
}];
}

內部發生兩種情況- (void)animateSequenceTemplate

  1. 我稱之為[self animateSequenceSlides]; 在這種情況下,動畫不會顯示。
  2. [self performSelector:@selector(animateSequenceSlides) withObject:nil afterDelay:0.0f]; 在這種情況下,動畫將顯示出來,但是在scrollview靜止之后。

我被迫使用執行選擇器來使用UIView動畫,因為如果刪除它並使用嵌套的UIView動畫塊/或直接調用這些方法,則動畫不會再次顯示。 現在至少在我靜止滾動后才顯示出來。

我想提出解決方案的建議,或者對我可能犯的錯誤有任何猜測。

您有可能不在主隊列上執行它。

dispatch_async(dispatch_get_main_queue, block())可能會有所幫助。 使用動畫時,主隊列是執行代碼的唯一位置,這使動畫發生。

編輯:

[self performSelector:@selector(animationPhase1) withObject:nil afterDelay:delay];

我不確定它在哪里發生,但我不認為在主線程上。 嘗試這個:

[self performSelectorOnMainThread:@selector(animationPhase1) 
                       withObject:nil 
                    waitUntilDone:YES];

我不確定延遲,這就是為什么我更喜歡GCD功能和塊。

終於,我得到了我的問題的解決方案,並且按預期工作得很好。

所做的更改:

  1. 從“ animateSequenceTemplate”中,直接調用“ animateSequenceSlides”方法
  2. 在上述“ animateSlideView”方法中,我沒有使用執行選擇器,而是創建了具有所需延遲的NSTimer對象,將其重復設置為NO,並在當前運行循環中添加了計時器
  3. 調用所有四個animationPhase方法的操作相同
  4. 代碼可以正常工作

      - (void)animateSequenceTemplate { if (!hasSequenceTemplateAnimated && self.isSequenceSlideCreated) { hasSequenceTemplateAnimated = YES; [self animateSequenceSlides]; } } - (void)animateSlideView:(NSNotification *)notification { NSDictionary *userInfo = notification.userInfo; if ([userInfo objectForKey:@"assetMO"] == assetMO) { [[NSNotificationCenter defaultCenter]removeObserver:self name:AnimateSequenceSlide object:nil]; CGFloat duration = 0.035; float delay = (self.slideCount * duration); CGFloat timeDelay = 0; NSTimer *animate1 = [NSTimer scheduledTimerWithTimeInterval:delay target:self selector:@selector(animationPhase1) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop]addTimer:animate1 forMode:NSRunLoopCommonModes]; timeDelay = delay + duration; NSTimer *animate2 = [NSTimer scheduledTimerWithTimeInterval:timeDelay target:self selector:@selector(animationPhase2) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop]addTimer:animate2 forMode:NSRunLoopCommonModes]; if (self.slideCount == (self.maxSlideCount - 1)) { timeDelay += duration * 18; //No animation till 18 frames } else { timeDelay += duration; } NSTimer *animate3 = [NSTimer scheduledTimerWithTimeInterval:timeDelay target:self selector:@selector(animationPhase3) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop]addTimer:animate3 forMode:NSRunLoopCommonModes]; timeDelay += duration; NSTimer *animate4 = [NSTimer scheduledTimerWithTimeInterval:timeDelay target:self selector:@selector(animationPhase4) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop]addTimer:animate4 forMode:NSRunLoopCommonModes]; } } 

我對代碼結構的好處不滿意。 如果您有其他明智的做法,請分享。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM