From 15765bdacd94b4b088548e7b389a0cf204a5de62 Mon Sep 17 00:00:00 2001 From: Almaz Ibragimov Date: Thu, 15 Jun 2023 11:07:01 +0300 Subject: [PATCH] Bottom sheet improvements (#101) --- .../BottomSheetDetentionController.swift | 26 ++++++++++++++++--- .../BottomSheetDismissingInteraction.swift | 2 +- .../BottomSheetPresentedInteraction.swift | 4 +-- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/Sources/Addons/BottomSheet/Detention/BottomSheetDetentionController.swift b/Sources/Addons/BottomSheet/Detention/BottomSheetDetentionController.swift index e53f47c2..ddce0f27 100644 --- a/Sources/Addons/BottomSheet/Detention/BottomSheetDetentionController.swift +++ b/Sources/Addons/BottomSheet/Detention/BottomSheetDetentionController.swift @@ -5,6 +5,7 @@ internal final class BottomSheetDetentionController { private var cachedDetentValues: [BottomSheetDetentKey: CGFloat?] = [:] + private var cachedSmallestDetentValueIgnoringKeyboard: CGFloat? private var cachedSmallestDetentValue: CGFloat? private var cachedLargestDetentValue: CGFloat? private var cachedCurrentDetentValue: CGFloat? @@ -13,6 +14,7 @@ internal final class BottomSheetDetentionController { internal var keyboardHeight: CGFloat = .zero { didSet { + cachedSmallestDetentValue = nil cachedLargestDetentValue = nil cachedCurrentDetentValue = nil } @@ -71,6 +73,20 @@ internal final class BottomSheetDetentionController { return resolveDetentValue(detent: detent) } + internal func resolveSmallestDetentValueIgnoringKeyboard() -> CGFloat { + if let cachedSmallestDetentValueIgnoringKeyboard { + return cachedSmallestDetentValueIgnoringKeyboard + } + + let smallestDetentValue = detents + .compactMap(resolveDetentValue(detent:)) + .min() ?? .zero + + cachedSmallestDetentValueIgnoringKeyboard = smallestDetentValue + + return smallestDetentValue + } + internal func resolveSmallestDetentValue() -> CGFloat { if let cachedSmallestDetentValue { return cachedSmallestDetentValue @@ -78,9 +94,10 @@ internal final class BottomSheetDetentionController { let smallestDetentValue = detents .compactMap(resolveDetentValue(detent:)) - .min() ?? .zero + .min() + .map { min($0 + keyboardHeight, maximumDetentValue) } ?? .zero - self.cachedSmallestDetentValue = smallestDetentValue + cachedSmallestDetentValue = smallestDetentValue return smallestDetentValue } @@ -95,7 +112,7 @@ internal final class BottomSheetDetentionController { .max() .map { min($0 + keyboardHeight, maximumDetentValue) } ?? .zero - self.cachedLargestDetentValue = largestDetentValue + cachedLargestDetentValue = largestDetentValue return largestDetentValue } @@ -116,7 +133,7 @@ internal final class BottomSheetDetentionController { .map { min($0 + self.keyboardHeight, self.maximumDetentValue) } .min() ?? .zero - self.cachedCurrentDetentValue = currentDetentValue + cachedCurrentDetentValue = currentDetentValue return currentDetentValue } @@ -159,6 +176,7 @@ internal final class BottomSheetDetentionController { internal func invalidateDetents() { cachedDetentValues = [:] + cachedSmallestDetentValueIgnoringKeyboard = nil cachedSmallestDetentValue = nil cachedLargestDetentValue = nil cachedCurrentDetentValue = nil diff --git a/Sources/Addons/BottomSheet/Interaction/Interactions/BottomSheetDismissingInteraction.swift b/Sources/Addons/BottomSheet/Interaction/Interactions/BottomSheetDismissingInteraction.swift index 5d7742a3..acea8133 100644 --- a/Sources/Addons/BottomSheet/Interaction/Interactions/BottomSheetDismissingInteraction.swift +++ b/Sources/Addons/BottomSheet/Interaction/Interactions/BottomSheetDismissingInteraction.swift @@ -171,7 +171,7 @@ internal final class BottomSheetDismissingInteraction: BottomSheetInteraction { let smallestDetentValue = presentationController .detention - .resolveSmallestDetentValue() + .resolveSmallestDetentValueIgnoringKeyboard() if gesturePredictedValue > 0.5 * smallestDetentValue { presentationController.transition.cancel() diff --git a/Sources/Addons/BottomSheet/Interaction/Interactions/BottomSheetPresentedInteraction.swift b/Sources/Addons/BottomSheet/Interaction/Interactions/BottomSheetPresentedInteraction.swift index 8113c491..a5c116b7 100644 --- a/Sources/Addons/BottomSheet/Interaction/Interactions/BottomSheetPresentedInteraction.swift +++ b/Sources/Addons/BottomSheet/Interaction/Interactions/BottomSheetPresentedInteraction.swift @@ -62,7 +62,7 @@ internal final class BottomSheetPresentedInteraction: BottomSheetInteraction { let smallestDetentValue = presentationController .detention - .resolveSmallestDetentValue() + .resolveSmallestDetentValueIgnoringKeyboard() if gestureValue < smallestDetentValue - .leastNonzeroMagnitude { let smallestDetentDelta = smallestDetentValue - currentDetentValue @@ -89,7 +89,7 @@ internal final class BottomSheetPresentedInteraction: BottomSheetInteraction { let smallestDetentValue = presentationController .detention - .resolveSmallestDetentValue() + .resolveSmallestDetentValueIgnoringKeyboard() let dismissalThreshold = isGestureFinished ? smallestDetentValue * 0.5