2012-08-28 31 views
3

我有一個組動畫,但無法檢測何時點擊animationDidStop。例如我的代碼:animationDidStop for group animation

[group setDelegate:self]; 
[view.layer addAnimation:group forKey:@"groupAnimation"]; 

任你知道我怎麼知道什麼時候該組動畫完成?

+1

__Be知道'CAAnimation'的'delegate'強,所以你可能需要將其設置爲'nil'避免保留週期!__ –

回答

11

您還需要設置animationName屬性相匹配,並確保您的委託功能正確定義:

CAAnimationGroup *group = [CAAnimationGroup animation]; 
group.duration = 2.0f; 
group.delegate = self; 
[group setValue:@"groupAnimation" forKey:@"animationName"]; 
[group setAnimations:[NSArray arrayWithObjects:myAnimation, myOtherAnimation, nil]]; 
[view.layer addAnimation:group forKey:@"groupAnimation"]; 

。 。 。

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished 
{ 
if (finished) 
{ 
    NSString *animationName = [animation valueForKey:@"animationName"]; 
    if ([animationName isEqualToString:@"groupAnimation"]) 
    { 
    // your groupAnimation has ended 
    } 
} 
} 

請注意,使用組動畫時,組件動畫上設置的代表將被忽略。

+2

你可能應該解釋一下,animationName是動畫上的一個自定義屬性(不是子類,而是當你使用setValue:forKey時被設置的屬性)以及它爲什麼可以工作(Core Animation可以爲任何值設置一個值其動畫鍵(正常類不以這種方式工作))等 –

+0

是的,謝謝@DavidRonnqvist,animationName是任意屬性,這裏僅用於識別動畫在animationDidStop委託方法完成。如果你只有一個動畫正在進行,你在技術上不需要這個...但是你確實需要正確定義的委託方法,這是你可能的問題。 – CSmith

+0

完美解決方案!非常感謝 。它真的幫了我很多 – ShineWang

1

我想出了一種組織好的動畫完成代碼的方法。首先,我定義的自定義類型的代碼塊時的動畫完成運行:

typedef void (^animationCompletionBlock)(void); 

我定義一個常數,我使用的自定義鍵值對添加到我的動畫:

#define kAnimationCompletionBlock @"animationCompletionBlock" 

然後,當我創建一個動畫,如果我想它,當它完成執行的代碼塊,我自定義屬性添加到我的動畫包含的代碼塊我要執行:

animationCompletionBlock theBlock; 
theBlock = ^void(void) 
{  
    someButton.enabled = TRUE; 
    NSLog(@"Animation complete"); 
    //whatever other code you want to do on completion 
} 

[myAnimation setValue: theBlock forKey: kAnimationCompletionBlock]; 

我設置了v IEW控制器是動畫的委託:

myAnimation.delegate = self 

最後,我寫看起來爲附連到動畫的動畫完成塊,並且如果它發現它執行它的通用動畫完成方法:

/* 
This method looks for a value added to the animation that just completed 
with the key kAnimationCompletionBlock. 
If it exists, it assumes it is a code block of type animationCompletionBlock, 
and executes the code block. 
This allows you to add a custom block of completion code to any animation or 
animation group, rather than Having a big complicated switch statement in your 
animationDidStop:finished: method with global animation ompletion code. 
(Note that the system won't call the animationDidStop:finished method for 
individual animations in an animation group - it will only call the 
completion method for the entire group. Thus, if you want to run code after 
part of an animation group completes, you have to set up a manual timer.) 
*/ 

- (void)animationDidStop:(CAAnimation *)theAnimation 
    finished:(BOOL)flag 
{ 
    animationCompletionBlock theBlock = 
    [theAnimation valueForKey: kAnimationCompletionBlock]; 
    if (theBlock) 
    theBlock(); 
} 

除了非常乾淨之外,此方法還允許您的動畫完成代碼訪問位於您定義塊的範圍內的局部變量。這解決了將信息傳遞給完成方法的問題,這可能很困難。

你可以看到在一個工作示例程序這個技術我發佈到Github上:

Core Animation demo on Github, including completion block code

+0

隨着swift3的一些更新,這肯定會是最優雅的動畫。您可以創建幾個擴展,將可以很容易地寫一些東西,比如'addAnimation(動畫,完成:)' –

2

我使用這個類別設置完成這樣的:

[group setCompletionBlock:^{ 

}]; 

第一個CAAnimationGroup + Blocks.h:

#import <QuartzCore/QuartzCore.h> 
#import <objc/runtime.h> 

typedef void (^TIFAnimationGroupCompletionBlock)(); 

@interface CAAnimationGroup (Blocks) 

- (void)setCompletionBlock:(TIFAnimationGroupCompletionBlock)handler; 

@end 

而且CAAnimationGroup + Blocks.m:

#import "CAAnimationGroup+Blocks.h" 

static char CAAnimationGroupBlockKey; 

@implementation CAAnimationGroup (Blocks) 

- (void)setCompletionBlock:(TIFAnimationGroupCompletionBlock)handler { 
    objc_setAssociatedObject(self, &CAAnimationGroupBlockKey, handler, OBJC_ASSOCIATION_COPY_NONATOMIC); 

    self.delegate = self; 
} 

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished 
{ 
    if (finished) 
    { 
     TIFAnimationGroupCompletionBlock handler = (TIFAnimationGroupCompletionBlock)objc_getAssociatedObject(self, &CAAnimationGroupBlockKey); 
     if (handler) { 
      handler(); 
     } 
    } 
} 

@end 
+0

我得到這個錯誤的'self.delegate =自我;' - 分配到「身份證 _Nullable」從不兼容的類型'CAAnimationGroup * const __strong' –