1 // Copyright (c) 2018, Applidium. All rights reserved 2 // OverlayAnimationCoordinator.swift 3 // OverlayContainer 4 // 5 // Created by Gaétan Zanella on 14/11/2018. 6 // 7 8 import UIKit 9 10 /// A protocol that provides information about the current overlay translation. 11 public protocol OverlayContainerTransitionContext { 12 /// A Boolean value that indicates whether the user is currently dragging the overlay. 13 var isDragging: Bool { get } 14 /// The overlay velocity. 15 var velocity: CGPoint { get } 16 /// The current translation height. 17 var overlayTranslationHeight: CGFloat { get } 18 /// The notch indexes. 19 var notchIndexes: Range<Int> { get } 20 /// The reachable indexes. Some indexes might be disabled by the `canReachNotchAt` delegate method. 21 var reachableIndexes: [Int] { get } 22 /// Returns the height of the specified notch. heightnull23 func height(forNotchAt index: Int) -> CGFloat 24 } 25 26 public extension OverlayContainerTransitionContext { 27 28 func minimumReachableHeight() -> CGFloat { 29 return reachableIndexes.first.flatMap { height(forNotchAt: $0) } ?? 0 30 } 31 32 func maximumReachableHeight() -> CGFloat { 33 return reachableIndexes.last.flatMap { height(forNotchAt: $0) } ?? 0 34 } 35 36 func minimumHeight() -> CGFloat { 37 return notchIndexes.first.flatMap { height(forNotchAt: $0) } ?? 0 38 } 39 40 func maximumHeight() -> CGFloat { 41 return notchIndexes.last.flatMap { height(forNotchAt: $0) } ?? 0 42 } 43 } 44 45 46 /// A protocol that provides information about an in-progress translation. 47 /// Do not adopt this protocol in your own classes. Use the one provided by the `OverlayContainerTransitionCoordinator`. 48 public protocol OverlayContainerTransitionCoordinatorContext: OverlayContainerTransitionContext { 49 /// A Boolean value indicating whether the transition is explicitly animated. 50 var isAnimated: Bool { get } 51 /// A Boolean value indicating whether the transition was cancelled. 52 var isCancelled: Bool { get } 53 /// The overlay height the container expects to reach. 54 var targetTranslationHeight: CGFloat { get } 55 } 56 57 /// A protocol that provides support for animations associated with an overlay translation. 58 /// 59 /// Do not adopt this procotol in your own classes. Use the one provided by the `OverlayContainerDelegate` to 60 /// add any extra animations alongside the translation animations. 61 public protocol OverlayContainerTransitionCoordinator: OverlayContainerTransitionCoordinatorContext { 62 /// Runs the specified animations at the same time as overlay translation end animations. 63 func animate(alongsideTransition animation: ((OverlayContainerTransitionCoordinatorContext) -> Void)?, 64 completion: ((OverlayContainerTransitionCoordinatorContext) -> Void)?) 65 } 66 67 public extension OverlayContainerTransitionCoordinatorContext { 68 translationProgressnull69 func translationProgress() -> CGFloat { 70 let maximum = maximumReachableHeight() 71 let minimum = minimumReachableHeight() 72 return maximum != minimum ? (targetTranslationHeight - minimum) / (maximum - minimum) : 0 73 } 74 overallTranslationProgressnull75 func overallTranslationProgress() -> CGFloat { 76 let maximum = maximumHeight() 77 let minimum = minimumHeight() 78 return maximum != minimum ? (targetTranslationHeight - minimum) / (maximum - minimum) : 0 79 } 80 } 81