Quantcast
Channel:
Viewing all articles
Browse latest Browse all 27

CAAnimation completion callback block

$
0
0

It’s really useful to fire a function when an animation is complete.
There’s no built in way to do that in CoreAnimation, it does have the concept of delegate’s, which get you half way there.

However if you have multiple animations firing, and your delegate is catching everything, you’re gonna be in for a world of hurt.

Here is a simple Swift class I wrote to extend CAAnimation to accept onStart/onCompletion blocks:

import Foundation
import Cocoa

public typealias CAAnimationCallback = (CAAnimation) -> ();

public class CAAnimationDelegate:NSObject {
  var animation:CAAnimation!;
  var onStartCallback:CAAnimationCallback?
  var onCompleteCallback:CAAnimationCallback?

  init(_ anim:CAAnimation) {
    animation = anim;
  }

  deinit {
    animation.delegate = nil;
    animation = nil;
    onStartCallback = nil;
    onCompleteCallback = nil;
  }

  override public func animationDidStart(anim: CAAnimation) {
    if let startHandler = onStartCallback {
      startHandler(anim);
    }
  }

  override public func animationDidStop(anim: CAAnimation, finished flag: Bool) {
    if let completionHandler = onCompleteCallback {
      completionHandler(anim);
    }
  }
}

public extension CAAnimation {
  // See if there is already a CAAnimationDelegate handling this animation
  // If there is, add onStart to it, if not create one
  func setonStartCallbackBlock(callback:CAAnimationCallback) {
    if let myDelegate = delegate {
      if(myDelegate.isKindOfClass(CAAnimationDelegate)) {
        let myThing = myDelegate as! CAAnimationDelegate;
        myThing.onStartCallback = callback;
      }
    } else {
      let callbackDelegate = CAAnimationDelegate(self);
      callbackDelegate.onStartCallback = callback;
      self.delegate = callbackDelegate;
    }
  }

  // See if there is already a CAAnimationDelegate handling this animation
  // If there is, add onCompletion to it, if not create one
  func setCompletionBlock(callback:CAAnimationCallback) {
    if let myDelegate = delegate {
      if(myDelegate.isKindOfClass(CAAnimationDelegate)) {
        let myThing = myDelegate as! CAAnimationDelegate;
        myThing.onCompleteCallback = callback;
      }
    } else {
      let callbackDelegate = CAAnimationDelegate(self);
      callbackDelegate.onCompleteCallback = callback;
      self.delegate = callbackDelegate;
    }
  }
}

Usage

var animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = duration
animation.fromValue = 0.0
animation.toValue = 1.0
animation.setCompletionBlock({ (anim:CAAnimation) in
  Swift.print("On Complete!")
})

Viewing all articles
Browse latest Browse all 27

Trending Articles