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