12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- //
- // Created by jason akakpo on 01/01/2017.
- // Copyright © 2017 IBAnimatable. All rights reserved.
- //
- import Foundation
- import UIKit
- typealias AnimationTuple = (type: AnimationType, configuration: AnimationConfiguration)
- struct AnimationConfiguration {
- let damping: CGFloat
- let velocity: CGFloat
- let duration: TimeInterval
- let delay: TimeInterval
- let force: CGFloat
- let timingFunction: TimingFunctionType
- }
- extension AnimationConfiguration {
- /// Options for spring animation.
- var options: UIView.AnimationOptions {
- if let curveOption = timingFunction.viewAnimationCurveOption {
- return [
- .allowUserInteraction,
- curveOption,
- .overrideInheritedCurve,
- .overrideInheritedOptions,
- .overrideInheritedDuration]
- }
- return [.allowUserInteraction]
- }
- }
- public class AnimationPromise<T: UIView> where T: Animatable {
- private var view: T
- private var animationList = [AnimationTuple]()
- private var delayForNextAnimation = 0.0
- private var completion: AnimatableCompletion?
- init(view: T) {
- self.view = view
- }
- func animationCompleted() {
- animationList.removeFirst()
- if let currentAnimation = animationList.first {
- view.doAnimation(currentAnimation.type, configuration: currentAnimation.configuration, promise: self)
- } else {
- completion?()
- }
- }
- public func completion(_ completion: AnimatableCompletion?) {
- self.completion = completion
- }
- @discardableResult
- public func then(_ animation: AnimationType,
- duration: TimeInterval? = nil,
- damping: CGFloat? = nil,
- velocity: CGFloat? = nil,
- force: CGFloat? = nil,
- timingFunction: TimingFunctionType? = nil) -> AnimationPromise {
- let configuration = AnimationConfiguration(damping: damping ?? view.damping,
- velocity: velocity ?? view.velocity,
- duration: duration ?? view.duration,
- delay: delayForNextAnimation,
- force: force ?? view.force,
- timingFunction: timingFunction ?? view.timingFunction)
- let animTuple = AnimationTuple(type: animation, configuration: configuration)
- animationList.append(animTuple)
- if animationList.count == 1 { // If it's the only animation, launch it immediately
- view.doAnimation(animation, configuration: animTuple.configuration, promise: self)
- }
- delayForNextAnimation = 0
- return self
- }
- @discardableResult
- public func delay(_ delay: TimeInterval) -> AnimationPromise {
- delayForNextAnimation = delay
- return self
- }
- }
|