1 //  Copyright (c) 2018, Applidium. All rights reserved
2 //  OverlayContainerPresentationController.swift
3 //
4 //
5 //  Created by Gaétan Zanella on 07/04/2020.
6 //
7 
8 import UIKit
9 
10 /// An abstract class that can be used to manage the transition animations and the presentation of overlay containers onscreen.
11 ///
12 /// Any overlay containers currently in the presented view controller hierarchy will be coupled with it.
13 /// It lets you add custom presentation behaviors based on the current state of the presented overlay containers.
14 ///
15 /// This class is meant to be subclassed. Before you consider subclassing, though, you should look at
16 /// the `OverlayContainerSheetPresentationController` class to see if it can be adapted to your presentation behavior.
17 open class OverlayContainerPresentationController: UIPresentationController {
18 
19     // MARK: - Internal
20 
presentationTransitionWillBeginnull21     open override func presentationTransitionWillBegin() {
22         super.presentationTransitionWillBegin()
23         findPresentedContainers().forEach { $0.overlayContainerPresentationTransitionWillBegin() }
24     }
25 
dismissalTransitionDidEndnull26     open override func dismissalTransitionDidEnd(_ completed: Bool) {
27         super.dismissalTransitionDidEnd(completed)
28         findPresentedContainers().forEach { $0.overlayContainerDismissalTransitionDidEnd() }
29     }
30 
31     // MARK: - Public
32 
33     /// Tells the presentation controller when the user is about to start dragging the overlay view controller.
34     ///
35     /// - parameter containerViewController: The container requesting this information.
36     /// - parameter overlayViewController: The overlay view controller.
37     open func overlayContainerViewController(_ containerViewController: OverlayContainerViewController,
38                                              willStartDraggingOverlay overlayViewController: UIViewController) {}
39 
40     /// Tells the presentation controller when the user finishs dragging the overlay view controller with the specified velocity.
41     ///
42     /// - parameter containerViewController: The container requesting this information.
43     /// - parameter overlayViewController: The overlay view controller.
44     /// - parameter velocity: The overlay velocity at the moment the touch was released.
45     open func overlayContainerViewController(_ containerViewController: OverlayContainerViewController,
46                                              willEndDraggingOverlay overlayViewController: UIViewController,
47                                              atVelocity velocity: CGPoint) {}
48 
49     /// Tells the presentation controller when the container is about to move the overlay view controller to the specified notch.
50     ///
51     /// In some cases, the overlay view controller may not successfully reach the specified notch.
52     /// If the user cancels the translation for instance. Use `overlayContainerViewController(_:didMove:toNotchAt:)`
53     /// if you need to be notified each time the translation succeeds.
54     ///
55     /// - parameter containerViewController: The container requesting this information.
56     /// - parameter overlayViewController: The overlay view controller.
57     /// - parameter index: The notch index the overlay view controller is about to reach.
58     open func overlayContainerViewController(_ containerViewController: OverlayContainerViewController,
59                                              willMoveOverlay overlayViewController: UIViewController,
60                                              toNotchAt index: Int) {}
61 
62     /// Tells the presentation controller when the container has moved the overlay view controller to the specified notch.
63     ///
64     /// - parameter containerViewController: The container requesting this information.
65     /// - parameter overlayViewController: The overlay view controller.
66     /// - parameter index: The notch index the overlay view controller has reached.
67     open func overlayContainerViewController(_ containerViewController: OverlayContainerViewController,
68                                              didMoveOverlay overlayViewController: UIViewController,
69                                              toNotchAt index: Int) {}
70 
71     /// Tells the presentation controller whenever the overlay view controller is about to be translated.
72     ///
73     /// The delegate typically implements this method to coordinate presentation changes alongside
74     /// the overlay view controller translation.
75     ///
76     /// - parameter containerViewController: The container requesting this information.
77     /// - parameter overlayViewController: The overlay view controller.
78     /// - parameter transitionCoordinator: The transition coordinator object associated with the translation.
79     open func overlayContainerViewController(_ containerViewController: OverlayContainerViewController,
80                                              willTranslateOverlay overlayViewController: UIViewController,
81                                              transitionCoordinator: OverlayContainerTransitionCoordinator) {}
82 
83     // MARK: - Private
84 
findPresentedContainersnull85     private func findPresentedContainers() -> [OverlayContainerViewController] {
86         presentedViewController.oc_findChildren(OverlayContainerViewController.self)
87     }
88 }
89