123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- //
- // 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
- }
- }
|