SignatureCustomPresentationController.swift 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. //
  2. // AAPLCustomPresentationController.swift
  3. // ComPDFKit_Tools
  4. //
  5. // Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
  6. //
  7. // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
  8. // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
  9. // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
  10. // This notice may not be removed from this file.
  11. //
  12. import UIKit
  13. class SignatureCustomPresentationController: UIPresentationController,UIViewControllerTransitioningDelegate,UIViewControllerAnimatedTransitioning {
  14. var dimmingView:UIView?
  15. var presentationWrappingView:UIView?
  16. let CORNER_RADIUS: CGFloat = 16.0
  17. init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController) {
  18. super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
  19. presentedViewController.modalPresentationStyle = .custom
  20. }
  21. override var presentedView: UIView? {
  22. return presentationWrappingView
  23. }
  24. override func presentationTransitionWillBegin() {
  25. guard let presentedViewControllerView = super.presentedView else { return }
  26. let presentationWrapperView = UIView(frame: frameOfPresentedViewInContainerView)
  27. presentationWrapperView.layer.shadowOpacity = 0.44
  28. presentationWrapperView.layer.shadowRadius = 13
  29. presentationWrapperView.layer.shadowOffset = CGSize(width: 0, height: -6)
  30. presentationWrappingView = presentationWrapperView
  31. let presentationRoundedCornerView = UIView(frame: presentationWrapperView.bounds.inset(by: UIEdgeInsets(top: 0, left: 0, bottom: -CORNER_RADIUS, right: 0)))
  32. presentationRoundedCornerView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
  33. presentationRoundedCornerView.layer.cornerRadius = CORNER_RADIUS
  34. presentationRoundedCornerView.layer.masksToBounds = true
  35. let presentedViewControllerWrapperView = UIView(frame: presentationRoundedCornerView.bounds.inset(by: UIEdgeInsets(top: 0, left: 0, bottom: CORNER_RADIUS, right: 0)))
  36. presentedViewControllerWrapperView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
  37. presentedViewControllerView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
  38. presentedViewControllerView.frame = presentedViewControllerWrapperView.bounds
  39. presentedViewControllerWrapperView.addSubview(presentedViewControllerView)
  40. presentationRoundedCornerView.addSubview(presentedViewControllerWrapperView)
  41. presentationWrapperView.addSubview(presentationRoundedCornerView)
  42. if let containerView = self.containerView {
  43. let dimmingView = UIView(frame: containerView.bounds)
  44. dimmingView.backgroundColor = UIColor.init(red: 1, green: 1, blue: 1, alpha: 0.1)
  45. dimmingView.isOpaque = false
  46. dimmingView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
  47. dimmingView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(dimmingViewTapped)))
  48. self.dimmingView? = dimmingView
  49. containerView.addSubview(dimmingView)
  50. if let transitionCoordinator = presentingViewController.transitionCoordinator {
  51. self.dimmingView?.alpha = 0.0
  52. transitionCoordinator.animate(alongsideTransition: { (context) in
  53. self.dimmingView?.alpha = 0.5
  54. }, completion: nil)
  55. }
  56. }
  57. }
  58. override func presentationTransitionDidEnd(_ completed: Bool) {
  59. if completed == false {
  60. self.presentationWrappingView = nil
  61. self.dimmingView = nil
  62. }
  63. }
  64. override func dismissalTransitionWillBegin() {
  65. guard let transitionCoordinator = presentingViewController.transitionCoordinator else { return }
  66. transitionCoordinator.animate(alongsideTransition: { (context) in
  67. self.dimmingView?.alpha = 0.0
  68. }, completion: nil)
  69. }
  70. override func dismissalTransitionDidEnd(_ completed: Bool) {
  71. if completed == true {
  72. self.presentationWrappingView = nil
  73. self.dimmingView = nil
  74. }
  75. }
  76. // MARK: - Layout
  77. override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) {
  78. super.preferredContentSizeDidChange(forChildContentContainer: container)
  79. if container === presentedViewController {
  80. containerView?.setNeedsLayout()
  81. }
  82. }
  83. override func size(forChildContentContainer container: UIContentContainer, withParentContainerSize parentSize: CGSize) -> CGSize {
  84. if container === presentedViewController {
  85. return presentedViewController.preferredContentSize
  86. } else {
  87. return super.size(forChildContentContainer: container, withParentContainerSize: parentSize)
  88. }
  89. }
  90. override var frameOfPresentedViewInContainerView: CGRect {
  91. let containerViewBounds = containerView?.bounds ?? CGRect.zero
  92. let presentedViewContentSize = size(forChildContentContainer: presentedViewController, withParentContainerSize: containerViewBounds.size)
  93. var presentedViewControllerFrame = containerViewBounds
  94. presentedViewControllerFrame.size.height = presentedViewContentSize.height
  95. presentedViewControllerFrame.origin.y = containerViewBounds.maxY - presentedViewContentSize.height
  96. return presentedViewControllerFrame
  97. }
  98. override func containerViewWillLayoutSubviews() {
  99. super.containerViewWillLayoutSubviews()
  100. dimmingView?.frame = containerView?.bounds ?? CGRect.zero
  101. let width = containerView?.frame.size.width ?? 0
  102. presentationWrappingView?.frame = CGRect(x: (frameOfPresentedViewInContainerView.size.width - width)/2, y: frameOfPresentedViewInContainerView.origin.y, width: width, height: frameOfPresentedViewInContainerView.size.height)
  103. }
  104. // MARK: - Tap Gesture Recognizer
  105. @objc func dimmingViewTapped() {
  106. self.presentingViewController.dismiss(animated: true, completion: nil)
  107. }
  108. // MARK: - UIViewControllerAnimatedTransitioning
  109. func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
  110. return transitionContext?.isAnimated ?? false ? 0.35 : 0
  111. }
  112. func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
  113. guard let fromViewController = transitionContext.viewController(forKey: .from),
  114. let toViewController = transitionContext.viewController(forKey: .to) else {
  115. return
  116. }
  117. let containerView = transitionContext.containerView
  118. let toView = transitionContext.view(forKey: .to)
  119. let fromView = transitionContext.view(forKey: .from)
  120. let isPresenting = (fromViewController == presentingViewController)
  121. var fromViewFinalFrame = transitionContext.finalFrame(for: fromViewController)
  122. var toViewInitialFrame = transitionContext.initialFrame(for: toViewController)
  123. let toViewFinalFrame = transitionContext.finalFrame(for: toViewController)
  124. if(toView != nil) {
  125. containerView.addSubview(toView!)
  126. }
  127. if isPresenting {
  128. toViewInitialFrame.origin = CGPoint(x: containerView.bounds.minX, y: containerView.bounds.maxY)
  129. toViewInitialFrame.size = toViewFinalFrame.size
  130. toView?.frame = toViewInitialFrame
  131. } else {
  132. if(fromView != nil) {
  133. fromViewFinalFrame = fromView!.frame.offsetBy(dx: 0, dy: fromView!.frame.height)
  134. }
  135. }
  136. let transitionDuration = self.transitionDuration(using: transitionContext)
  137. UIView.animate(withDuration: transitionDuration, animations: {
  138. if isPresenting {
  139. toView?.frame = toViewFinalFrame
  140. } else {
  141. fromView?.frame = fromViewFinalFrame
  142. }
  143. }) { (finished) in
  144. let wasCancelled = transitionContext.transitionWasCancelled
  145. transitionContext.completeTransition(!wasCancelled)
  146. }
  147. }
  148. // MARK: - UIViewControllerTransitioningDelegate
  149. func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
  150. assert(self.presentedViewController == presented, "You didn’t initialize (self) with the correct presentedViewController. Expected (presented), got (self.presentedViewController)")
  151. return self
  152. }
  153. func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
  154. return self
  155. }
  156. func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
  157. return self
  158. }
  159. }