美文网首页iOS学习专题
iOS 完美解决CABasicAnimationDelegate

iOS 完美解决CABasicAnimationDelegate

作者: Sunrain16 | 来源:发表于2018-07-20 19:06 被阅读23次

    在自定义动画的时候,我们经常用到CABasicAnimation。网上介绍CABasicAnimation怎么使用的文章已经很多了。这里就不一一介绍了。在这里主要说一下CABasicAnimation代理使用的时候需要注意的一点:代理的弱引用。

    我们在使用CABasicAnimation的时候,如果直接设置动画代理,那么你这个view是不会走delloc进行释放的。Why?为什么?因为CABasicAnimation的代理强引用了动画执行的view。我们来看下系统API:

    /* The delegate of the animation. This object is retained for the
     * lifetime of the animation object. Defaults to nil. See below for the
     * supported delegate methods. */
    
    @property(nullable, strong) id <CAAnimationDelegate> delegate;
    

    你没有看错,苹果修饰代理的关键词使用的strong。所以执行动画的view的图层才不会走delloc。
    怎么解决呢?两个方法:

    0.不使用代理

    这种方法有些取巧。不使用代理,既然动画是自己写的,那肯定动画时长也是知道的。直接使用

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            <#code to be executed after a specified delay#>
    });
    

    执行动画完成之后的操作。但是有一个问题,万一某种原因导致动画时间改变了。逻辑就会出现问题,
    不够完美(做程序就要有一颗追求完美的心)。

    1.创建一个新的类,继承于CABasicAnimation,重写代理的方法

    关键代码:

    
    #import <Foundation/Foundation.h>
    #import <QuartzCore/QuartzCore.h>
    
    @protocol LEDStarAnimationDelgate<NSObject>
    
    @optional
    - (void)animationDidStop:(CAAnimation *)anim;
    
    @end
    
    @interface LEDAnimationDelegate : CABasicAnimation <CAAnimationDelegate>
    
    /** delegate */
    @property (nonatomic,weak) id<LEDStarAnimationDelgate> ledDelegate;
    
    @end
    

    ·································· 我是分割线 ······························

    #import "LEDAnimationDelegate.h"
    
    @implementation LEDAnimationDelegate
    
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
        if ([self.ledDelegate respondsToSelector:@selector(animationDidStop:)]) {
            [self.ledDelegate animationDidStop:anim];
        }
    }
    
    - (void)setLedDelegate:(id<LEDStarAnimationDelgate>)ledDelegate {
        _ledDelegate = ledDelegate;
        self.delegate = self;
    
    }
    
    - (void)dealloc {
        NSLog(@"dealloc");
    }
    
    @end
    

    使用的时候,不要使用CABasicAnimation,使用新创建的类。如下:

    LEDAnimationDelegate *opacityAnimation   = [LEDAnimationDelegate animationWithKeyPath:@"opacity"];
        opacityAnimation.fromValue               = [NSNumber numberWithFloat:1.0f];
        opacityAnimation.toValue                 = [NSNumber numberWithFloat:0.0f];
        opacityAnimation.beginTime               = CACurrentMediaTime() + self.frameTime + .7f;
        opacityAnimation.duration                = 0.01f;
        opacityAnimation.removedOnCompletion     = NO;
        opacityAnimation.fillMode                = kCAFillModeForwards;
        opacityAnimation.ledDelegate             = self;
    

    这样就完美解决了动画代理强引用动画执行view的问题。

    相关文章

      网友评论

        本文标题:iOS 完美解决CABasicAnimationDelegate

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