123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- //
- // AAPLCustomPresentationController.swift
- // ComPDFKit_Tools
- //
- // Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
- //
- // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
- // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
- // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
- // This notice may not be removed from this file.
- //
- import UIKit
- @objc public protocol AAPLCustomPresentationControllerDelegate: AnyObject {
-
- @objc optional func AAPLCustomPresentationControllerTap(_ customPresentationController: AAPLCustomPresentationController)
- }
- public class AAPLCustomPresentationController: UIPresentationController,UIViewControllerTransitioningDelegate,UIViewControllerAnimatedTransitioning {
-
- public weak var tapDelegate: AAPLCustomPresentationControllerDelegate?
-
- var dimmingView:UIView?
- var presentationWrappingView:UIView?
-
- let CORNER_RADIUS: CGFloat = 16.0
-
- public init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController) {
- super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
- presentedViewController.modalPresentationStyle = .custom
- }
-
- public override var presentedView: UIView? {
- return presentationWrappingView
- }
-
- public override func presentationTransitionWillBegin() {
- guard let presentedViewControllerView = super.presentedView else { return }
- let presentationWrapperView = UIView(frame: frameOfPresentedViewInContainerView)
- presentationWrapperView.layer.shadowOpacity = 0.44
- presentationWrapperView.layer.shadowRadius = 13
- presentationWrapperView.layer.shadowOffset = CGSize(width: 0, height: -6)
- presentationWrappingView = presentationWrapperView
-
- let presentationRoundedCornerView = UIView(frame: presentationWrapperView.bounds.inset(by: UIEdgeInsets(top: 0, left: 0, bottom: -CORNER_RADIUS, right: 0)))
- presentationRoundedCornerView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
- presentationRoundedCornerView.layer.cornerRadius = CORNER_RADIUS
- presentationRoundedCornerView.layer.masksToBounds = true
-
- let presentedViewControllerWrapperView = UIView(frame: presentationRoundedCornerView.bounds.inset(by: UIEdgeInsets(top: 0, left: 0, bottom: CORNER_RADIUS, right: 0)))
- presentedViewControllerWrapperView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
-
- presentedViewControllerView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
- presentedViewControllerView.frame = presentedViewControllerWrapperView.bounds
- presentedViewControllerWrapperView.addSubview(presentedViewControllerView)
-
- presentationRoundedCornerView.addSubview(presentedViewControllerWrapperView)
- presentationWrapperView.addSubview(presentationRoundedCornerView)
-
- if let containerView = self.containerView {
- let dimmingView = UIView(frame: containerView.bounds)
- dimmingView.backgroundColor = UIColor.black
- dimmingView.isOpaque = false
- dimmingView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
- dimmingView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(dimmingViewTapped)))
- self.dimmingView = dimmingView
- containerView.addSubview(dimmingView)
-
- if let transitionCoordinator = presentingViewController.transitionCoordinator {
- self.dimmingView?.alpha = 0.0
- transitionCoordinator.animate(alongsideTransition: { (context) in
- self.dimmingView?.alpha = 0.5
- }, completion: nil)
- }
- }
- }
-
- public override func presentationTransitionDidEnd(_ completed: Bool) {
- if completed == false {
- self.presentationWrappingView = nil
- self.dimmingView = nil
- }
- }
-
- public override func dismissalTransitionWillBegin() {
- guard let transitionCoordinator = presentingViewController.transitionCoordinator else { return }
- transitionCoordinator.animate(alongsideTransition: { (context) in
- self.dimmingView?.alpha = 0.0
- }, completion: nil)
-
- }
-
- public override func dismissalTransitionDidEnd(_ completed: Bool) {
- if completed == true {
- self.presentationWrappingView = nil
- self.dimmingView = nil
- }
- }
-
- // MARK: - Layout
- public override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) {
- super.preferredContentSizeDidChange(forChildContentContainer: container)
- if container === presentedViewController {
- containerView?.setNeedsLayout()
- }
-
- }
-
- public override func size(forChildContentContainer container: UIContentContainer, withParentContainerSize parentSize: CGSize) -> CGSize {
-
- if container === presentedViewController {
- return presentedViewController.preferredContentSize
- } else {
- return super.size(forChildContentContainer: container, withParentContainerSize: parentSize)
- }
- }
-
- public override var frameOfPresentedViewInContainerView: CGRect {
- let containerViewBounds = containerView?.bounds ?? CGRect.zero
- let presentedViewContentSize = size(forChildContentContainer: presentedViewController, withParentContainerSize: containerViewBounds.size)
- var presentedViewControllerFrame = containerViewBounds
- presentedViewControllerFrame.size.height = presentedViewContentSize.height
- presentedViewControllerFrame.origin.y = containerViewBounds.maxY - presentedViewContentSize.height
- return presentedViewControllerFrame
-
- }
- public override func containerViewWillLayoutSubviews() {
- super.containerViewWillLayoutSubviews()
- dimmingView?.frame = containerView?.bounds ?? CGRect.zero
- let width = min(containerView?.frame.size.width ?? 0, containerView?.frame.size.height ?? 0)
- presentationWrappingView?.frame = CGRect(x: (frameOfPresentedViewInContainerView.size.width - width)/2, y: frameOfPresentedViewInContainerView.origin.y, width: width, height: frameOfPresentedViewInContainerView.size.height)
-
- }
-
- // MARK: - Tap Gesture Recognizer
- @objc func dimmingViewTapped() {
- self.presentingViewController.dismiss(animated: true, completion: nil)
- self.tapDelegate?.AAPLCustomPresentationControllerTap?(self)
- }
-
- // MARK: - UIViewControllerAnimatedTransitioning
- public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
- return transitionContext?.isAnimated ?? false ? 0.35 : 0
- }
-
- public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
- guard let fromViewController = transitionContext.viewController(forKey: .from),
- let toViewController = transitionContext.viewController(forKey: .to) else {
- return
- }
-
- let containerView = transitionContext.containerView
-
- let toView = transitionContext.view(forKey: .to)
- let fromView = transitionContext.view(forKey: .from)
-
- let isPresenting = (fromViewController == presentingViewController)
-
- var fromViewFinalFrame = transitionContext.finalFrame(for: fromViewController)
- var toViewInitialFrame = transitionContext.initialFrame(for: toViewController)
- let toViewFinalFrame = transitionContext.finalFrame(for: toViewController)
-
- if(toView != nil) {
- containerView.addSubview(toView!)
- }
-
- if isPresenting {
- toViewInitialFrame.origin = CGPoint(x: containerView.bounds.minX, y: containerView.bounds.maxY)
- toViewInitialFrame.size = toViewFinalFrame.size
- toView?.frame = toViewInitialFrame
- } else {
- fromViewFinalFrame = fromView!.frame.offsetBy(dx: 0, dy: fromView!.frame.height)
- }
-
- let transitionDuration = self.transitionDuration(using: transitionContext)
-
- UIView.animate(withDuration: transitionDuration, animations: {
- if isPresenting {
- toView?.frame = toViewFinalFrame
- } else {
- fromView?.frame = fromViewFinalFrame
- }
- }) { (finished) in
- let wasCancelled = transitionContext.transitionWasCancelled
- transitionContext.completeTransition(!wasCancelled)
- }
- }
-
-
- // MARK: - UIViewControllerTransitioningDelegate
- public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
- assert(self.presentedViewController == presented, "You didn’t initialize (self) with the correct presentedViewController. Expected (presented), got (self.presentedViewController)")
- return self
-
- }
-
- public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
- return self
- }
-
- public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
- return self
- }
-
- }
|