-
Notifications
You must be signed in to change notification settings - Fork 2
/
Animator.swift
88 lines (74 loc) · 4.53 KB
/
Animator.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import UIKit
public class Animator {
public typealias AnimatorAnimationsClosure = () -> ()
public typealias AnimatorCompletionClosure = () -> ()
struct AnimationParameters {
enum Animationtype {
case withSpringDamping
case withoutSpringDamping
}
let duration: TimeInterval
let delay: TimeInterval
let options: UIViewAnimationOptions
let animationtype: Animationtype
let damping: CGFloat?
let initialVelocity: CGFloat?
init(duration: TimeInterval, delay: TimeInterval, options: UIViewAnimationOptions, animationtype: Animationtype) {
self.duration = duration
self.delay = delay
self.options = options
self.animationtype = animationtype
self.damping = nil
self.initialVelocity = nil
}
init(duration: TimeInterval, delay: TimeInterval, options: UIViewAnimationOptions, animationtype: Animationtype, damping: CGFloat, initialVelocity: CGFloat) {
self.duration = duration
self.delay = delay
self.options = options
self.animationtype = animationtype
self.damping = damping
self.initialVelocity = initialVelocity
}
}
private var animations = [(parameters: AnimationParameters, animationClosures: AnimatorAnimationsClosure)]()
public static func addAnimations(withDuration: TimeInterval = 1, delay: TimeInterval? = nil, options: UIViewAnimationOptions = [], animations: @escaping AnimatorAnimationsClosure) -> Animator {
let newAnimator = Animator()
let parameters = AnimationParameters(duration: withDuration, delay: delay ?? 0, options: options, animationtype: .withoutSpringDamping)
newAnimator.animations.append((parameters, animations))
return newAnimator
}
public static func addAnimations(withDuration: TimeInterval = 1, delay: TimeInterval? = nil, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions = [], animations: @escaping AnimatorAnimationsClosure) -> Animator {
let newAnimator = Animator()
let parameters = AnimationParameters(duration: withDuration, delay: delay ?? 0, options: options, animationtype: .withSpringDamping, damping: usingSpringWithDamping, initialVelocity: initialSpringVelocity)
newAnimator.animations.append((parameters, animations))
return newAnimator
}
public func addAnimations(withDuration: TimeInterval = 1, delay: TimeInterval? = nil, options: UIViewAnimationOptions = [], animations: @escaping AnimatorAnimationsClosure) -> Animator {
let parameters = AnimationParameters(duration: withDuration, delay: delay ?? 0, options: options,animationtype: .withoutSpringDamping)
self.animations.append((parameters, animations))
return self
}
public func addAnimations(withDuration: TimeInterval = 1, delay: TimeInterval? = nil, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions = [], animations: @escaping AnimatorAnimationsClosure) -> Animator {
let parameters = AnimationParameters(duration: withDuration, delay: delay ?? 0, options: options, animationtype: .withSpringDamping, damping: usingSpringWithDamping, initialVelocity: initialSpringVelocity)
self.animations.append((parameters, animations))
return self
}
public func animate(completion: AnimatorCompletionClosure? = nil) {
if let closureToAnimate = animations.first {
let parameters = closureToAnimate.parameters
if parameters.animationtype == .withoutSpringDamping {
UIView.animate(withDuration: parameters.duration, delay: parameters.delay, options: parameters.options, animations: closureToAnimate.animationClosures, completion: { (completed) in
self.animations.removeFirst()
self.animate(completion: completion)
})
} else {
UIView.animate(withDuration: parameters.duration, delay: parameters.delay, usingSpringWithDamping: parameters.damping ?? 0, initialSpringVelocity: parameters.initialVelocity ?? 0, options: parameters.options, animations: closureToAnimate.animationClosures, completion: { (completed) in
self.animations.removeFirst()
self.animate(completion: completion)
})
}
} else {
completion?()
}
}
}