1 //  Copyright (c) 2018, Applidium. All rights reserved
2 //  RushingForwardTargetNotchPolicy.swift
3 //  OverlayContainer
4 //
5 //  Created by Gaétan Zanella on 27/11/2018.
6 //
7 
8 import UIKit
9 
10 private struct Constant {
11     static let minimumDuration: CGFloat = 0.1
12     static let minimumVelocity: CGFloat = 400
13 }
14 
15 /// `RushingForwardTargetNotchPolicy` specifies a policy that will always move forward if a
16 /// minimum velocity has been reached.
17 public class RushingForwardTargetNotchPolicy: OverlayTranslationTargetNotchPolicy {
18 
19     /// The minimum velocity to reach to move forward. The default value is 400 pt/s.
20     public var minimumVelocity: CGFloat = Constant.minimumVelocity
21     /// The minimum duration defines the minimum translation duration to expect.
22     public var minimumDuration: CGFloat = Constant.minimumDuration
23 
24     // MARK: - Life Cycle
25 
26     public init() {}
27 
28     // MARK: - OverlayTranslationTargetNotchPolicy
29 
targetNotchIndexnull30     public func targetNotchIndex(using context: OverlayContainerContextTargetNotchPolicy) -> Int {
31         guard !context.reachableIndexes.isEmpty else { return 0 }
32         let height = minimumDuration * -context.velocity.y + context.overlayTranslationHeight
33         let closestNotches = context.reachableIndexes.sorted {
34             let lhsHeight = context.height(forNotchAt: $0)
35             let rhsHeight = context.height(forNotchAt: $1)
36             let lhsDistance = abs(height - lhsHeight)
37             let rhsDistance = abs(height - rhsHeight)
38             return (lhsDistance, lhsHeight) < (rhsDistance, rhsHeight)
39         }
40         if context.reachableIndexes.count > 1 && abs(context.velocity.y) > minimumVelocity {
41             let lhs = closestNotches[0]
42             let rhs = closestNotches[1]
43             if context.velocity.y < 0 {
44                 return max(lhs, rhs)
45             } else {
46                 return min(lhs, rhs)
47             }
48         } else {
49             return closestNotches.first ?? 0
50         }
51     }
52 }
53