92 lines
2.3 KiB
Swift
92 lines
2.3 KiB
Swift
//
|
|
// AnimationContext.swift
|
|
// lottie-swift
|
|
//
|
|
// Created by Brandon Withrow on 2/1/19.
|
|
//
|
|
|
|
import CoreGraphics
|
|
import Foundation
|
|
import QuartzCore
|
|
|
|
/// A completion block for animations. `true` is passed in if the animation completed playing.
|
|
public typealias LottieCompletionBlock = (Bool) -> Void
|
|
|
|
// MARK: - AnimationContext
|
|
|
|
struct AnimationContext {
|
|
|
|
init(
|
|
playFrom: AnimationFrameTime,
|
|
playTo: AnimationFrameTime,
|
|
closure: LottieCompletionBlock?)
|
|
{
|
|
self.playTo = playTo
|
|
self.playFrom = playFrom
|
|
self.closure = AnimationCompletionDelegate(completionBlock: closure)
|
|
}
|
|
|
|
var playFrom: AnimationFrameTime
|
|
var playTo: AnimationFrameTime
|
|
var closure: AnimationCompletionDelegate
|
|
|
|
}
|
|
|
|
// MARK: Equatable
|
|
|
|
extension AnimationContext: Equatable {
|
|
/// Whether or not the two given `AnimationContext`s are functionally equivalent
|
|
/// - This checks whether or not a completion handler was provided,
|
|
/// but does not check whether or not the two completion handlers are equivalent.
|
|
static func == (_ lhs: AnimationContext, _ rhs: AnimationContext) -> Bool {
|
|
lhs.playTo == rhs.playTo
|
|
&& lhs.playFrom == rhs.playFrom
|
|
&& (lhs.closure.completionBlock == nil) == (rhs.closure.completionBlock == nil)
|
|
}
|
|
}
|
|
|
|
// MARK: - AnimationContextState
|
|
|
|
enum AnimationContextState {
|
|
case playing
|
|
case cancelled
|
|
case complete
|
|
}
|
|
|
|
// MARK: - AnimationCompletionDelegate
|
|
|
|
class AnimationCompletionDelegate: NSObject, CAAnimationDelegate {
|
|
|
|
// MARK: Lifecycle
|
|
|
|
init(completionBlock: LottieCompletionBlock?) {
|
|
self.completionBlock = completionBlock
|
|
super.init()
|
|
}
|
|
|
|
// MARK: Public
|
|
|
|
public func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
|
|
guard ignoreDelegate == false else { return }
|
|
animationState = flag ? .complete : .cancelled
|
|
if let animationLayer = animationLayer, let key = animationKey {
|
|
animationLayer.removeAnimation(forKey: key)
|
|
if flag {
|
|
animationLayer.currentFrame = (anim as! CABasicAnimation).toValue as! CGFloat
|
|
}
|
|
}
|
|
if let completionBlock = completionBlock {
|
|
completionBlock(flag)
|
|
}
|
|
}
|
|
|
|
// MARK: Internal
|
|
|
|
var animationLayer: RootAnimationLayer?
|
|
var animationKey: String?
|
|
var ignoreDelegate = false
|
|
var animationState: AnimationContextState = .playing
|
|
|
|
let completionBlock: LottieCompletionBlock?
|
|
}
|