forked from SwipeCellKit/SwipeCellKit
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathSwipeAnimator.swift
112 lines (87 loc) · 3.03 KB
/
SwipeAnimator.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//
// SwipeAnimator.swift
//
// Created by Jeremy Koch
// Copyright © 2017 Jeremy Koch. All rights reserved.
//
import UIKit
protocol SwipeAnimator {
/// A Boolean value indicating whether the animation is currently running.
var isRunning: Bool { get }
/**
The animation to be run by the SwipeAnimator
- parameter animation: The closure to be executed by the animator
*/
func addAnimations(_ animation: @escaping () -> Void)
/**
Completion handler for the animation that is going to be started
- parameter completion: The closure to be execute on completion of the animator
*/
func addCompletion(completion: @escaping (Bool) -> Void)
/**
Starts the defined animation
*/
func startAnimation()
/**
Starts the defined animation after the given delay
- parameter delay: Delay of the animation
*/
func startAnimation(afterDelay delay: TimeInterval)
/**
Stops the animations at their current positions.
- parameter withoutFinishing: A Boolean indicating whether any final actions should be performed.
*/
func stopAnimation(_ withoutFinishing: Bool)
}
@available(iOS 10.0, *)
extension UIViewPropertyAnimator: SwipeAnimator {
func addCompletion(completion: @escaping (Bool) -> Void) {
addCompletion { position in
completion(position == .end)
}
}
}
class UIViewSpringAnimator: SwipeAnimator {
var isRunning: Bool = false
let duration:TimeInterval
let damping:CGFloat
let velocity:CGFloat
var animations:(() -> Void)?
var completion:((Bool) -> Void)?
required init(duration: TimeInterval,
damping: CGFloat,
initialVelocity velocity: CGFloat = 0) {
self.duration = duration
self.damping = damping
self.velocity = velocity
}
func addAnimations(_ animations: @escaping () -> Void) {
self.animations = animations
}
func addCompletion(completion: @escaping (Bool) -> Void) {
self.completion = { [weak self] finished in
guard self?.isRunning == true else { return }
self?.isRunning = false
self?.animations = nil
self?.completion = nil
completion(finished)
}
}
func startAnimation() {
self.startAnimation(afterDelay: 0)
}
func startAnimation(afterDelay delay:TimeInterval) {
guard let animations = animations else { return }
isRunning = true
UIView.animate(withDuration: duration,
delay: delay,
usingSpringWithDamping: damping,
initialSpringVelocity: velocity,
options: [.curveEaseInOut, .allowUserInteraction],
animations: animations,
completion: completion)
}
func stopAnimation(_ withoutFinishing: Bool) {
isRunning = false
}
}