123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- //
- // Created by Tom Baranes on 13/08/16.
- // Copyright © 2016 IBAnimatable. All rights reserved.
- //
- import UIKit
- public class DropDownAnimator: NSObject, AnimatedPresenting {
- // MARK: - AnimatedPresenting
- public var transitionDuration: Duration = defaultTransitionDuration
- fileprivate var timingFunctions: [TimingFunctionType] = [.easeOut, .linear, .easeOut]
- fileprivate var completion: AnimatableCompletion?
- // MARK: - Life cycle
- public init(duration: Duration) {
- transitionDuration = duration
- super.init()
- }
- }
- // MARK: - Animator
- extension DropDownAnimator: UIViewControllerAnimatedTransitioning {
- public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
- return retrieveTransitionDuration(transitionContext: transitionContext)
- }
- public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
- let (fromView, toView, tempContainerView) = retrieveViews(transitionContext: transitionContext)
- let isPresenting = self.isPresenting(transitionContext: transitionContext)
- guard let containerView = tempContainerView, let animatingView = isPresenting ? toView : fromView else {
- transitionContext.completeTransition(true)
- return
- }
- if isPresenting {
- containerView.addSubview(animatingView)
- }
- animateDropDown(animatingView: animatingView, isPresenting: isPresenting) {
- if !isPresenting {
- fromView?.removeFromSuperview()
- }
- transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
- }
- }
- }
- // MARK: - Animation
- private extension DropDownAnimator {
- func animateDropDown(animatingView: UIView, isPresenting: Bool, completion: @escaping AnimatableCompletion) {
- if isPresenting {
- animatePresengingDropDown(animatingView: animatingView, completion: completion)
- } else {
- animateDismissingDropDown(animatingView: animatingView, completion: completion)
- }
- }
- func animatePresengingDropDown(animatingView: UIView, completion: @escaping AnimatableCompletion) {
- let y = animatingView.center.y
- let animation = CAKeyframeAnimation(keyPath: .positionY)
- animation.values = [y - UIScreen.main.bounds.height, y + 20, y - 10, y]
- animation.keyTimes = [0, 0.5, 0.75, 1]
- animation.timingFunctionsType = timingFunctions
- animation.duration = transitionDuration
- animation.delegate = self
- self.completion = completion
- animatingView.layer.add(animation, forKey: "dropdown")
- }
- func animateDismissingDropDown(animatingView: UIView, completion: @escaping AnimatableCompletion) {
- var point = animatingView.center
- let angle = CGFloat(arc4random_uniform(100)) - 50
- point.y += UIScreen.main.bounds.height
- UIView.animate(withDuration: transitionDuration, animations: {
- animatingView.center = point
- animatingView.transform = CGAffineTransform(rotationAngle: angle / 100)
- }, completion: { _ in
- completion()
- })
- }
- }
- // MARK: - CAAnimationDelegate
- extension DropDownAnimator: CAAnimationDelegate {
- public func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
- if let completion = completion {
- completion()
- self.completion = nil
- }
- }
- }
|