// // PopupAnimators.swift // JiuLaiBao // // Created by Dan Jiang on 2018/11/14. // Copyright © 2018 GuoXiaoMei. All rights reserved. // import UIKit public protocol PopupAnimatable { var animateOverlayView: UIView { get } var animateContentView: UIView { get } var animateWidth: CGFloat { get } var animateHeight: CGFloat { get } var animateOverlayAlpha: CGFloat { get } } public extension PopupAnimatable { var animateWidth: CGFloat { return 0 } var animateHeight: CGFloat { return 0 } var animateOverlayAlpha: CGFloat { return 0 } } public class PopupAlertAnimator: NSObject, UIViewControllerAnimatedTransitioning { public var isPresented = true public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { if isPresented { return 0.3 } else { return 0.15 } } public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let containerView = transitionContext.containerView var animatedKey: UITransitionContextViewControllerKey = .from if isPresented { animatedKey = .to } guard let toViewController = transitionContext.viewController(forKey: .to), let toView = toViewController.view, let animatedViewController = transitionContext.viewController(forKey: animatedKey), let animatable = animatedViewController as? PopupAnimatable else { print("!!! Error: popup animation is not allowed !!!") return } let contentView = animatable.animateContentView if isPresented { containerView.addSubview(toView) } let duration = transitionDuration(using: transitionContext) if isPresented { UIView.animateKeyframes(withDuration: duration, delay: 0, options: [], animations: { UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5, animations: { contentView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2) }) UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5, animations: { contentView.transform = .identity }) }, completion: { _ in transitionContext.completeTransition(!transitionContext.transitionWasCancelled) }) } else { UIView.animate(withDuration: duration, delay: 0, options: [.curveEaseInOut], animations: { contentView.alpha = 0 }, completion: { _ in transitionContext.completeTransition(!transitionContext.transitionWasCancelled) }) } } } public class PopupSheetAnimator: NSObject, UIViewControllerAnimatedTransitioning { public var isPresented = true public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return 0.3 } public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let containerView = transitionContext.containerView var animatedKey: UITransitionContextViewControllerKey = .from if isPresented { animatedKey = .to } guard let toViewController = transitionContext.viewController(forKey: .to), let toView = toViewController.view, let animatedViewController = transitionContext.viewController(forKey: animatedKey), let animatable = animatedViewController as? PopupAnimatable else { print("!!! Error: popup animation is not allowed !!!") return } let contentView = animatable.animateContentView if isPresented { containerView.addSubview(toView) toView.layoutIfNeeded() } let duration = transitionDuration(using: transitionContext) let contentViewHeight = contentView.bounds.size.height let moveOut = CGAffineTransform(translationX: 0, y: contentViewHeight) if isPresented { contentView.transform = moveOut UIView.animate(withDuration: duration, delay: 0, options: [.curveEaseInOut], animations: { contentView.transform = .identity }, completion: { _ in transitionContext.completeTransition(!transitionContext.transitionWasCancelled) }) } else { UIView.animate(withDuration: duration, delay: 0, options: [.curveEaseInOut], animations: { contentView.transform = moveOut }, completion: { _ in transitionContext.completeTransition(!transitionContext.transitionWasCancelled) }) } } } public class PopupScaleAnimator: NSObject, UIViewControllerAnimatedTransitioning { public var isPresented = true public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return 0.2 } public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let containerView = transitionContext.containerView var animatedKey: UITransitionContextViewControllerKey = .from if isPresented { animatedKey = .to } guard let toViewController = transitionContext.viewController(forKey: .to), let toView = toViewController.view, let animatedViewController = transitionContext.viewController(forKey: animatedKey), let animatable = animatedViewController as? PopupAnimatable else { print("!!! Error: popup animation is not allowed !!!") return } let contentView = animatable.animateContentView let overlayView = animatable.animateOverlayView let overlayAlpha = animatable.animateOverlayAlpha if isPresented { containerView.addSubview(toView) toView.frame = containerView.bounds } let duration = transitionDuration(using: transitionContext) if isPresented { overlayView.alpha = 0 contentView.transform = CGAffineTransform(scaleX: 0, y: 0) UIView.animate(withDuration: duration, animations: { overlayView.alpha = overlayAlpha contentView.transform = .identity }, completion: { _ in transitionContext.completeTransition(!transitionContext.transitionWasCancelled) }) } else { UIView.animate(withDuration: duration, animations: { overlayView.alpha = 0 contentView.alpha = 0 contentView.transform = CGAffineTransform(scaleX: 0.1, y: 0.1) }, completion: { _ in transitionContext.completeTransition(!transitionContext.transitionWasCancelled) }) } } }