From ef7f00dab7258f1f76a4aba91ea1792a77452ab7 Mon Sep 17 00:00:00 2001 From: Stephen Sowole Date: Wed, 20 Mar 2019 13:58:17 -0700 Subject: [PATCH] Replace `isPanScrollEnabled` with `shouldRespond(to ..` (#10) * Replace `isPanScrollEnabled` with `shouldRespond(to ..` * Update PanModalPresentable+Defaults.swift --- .../PanModalPresentationController.swift | 24 ++++++++++++++++--- .../PanModalPresentable+Defaults.swift | 10 ++++---- .../Presentable/PanModalPresentable.swift | 19 +++++++-------- Tests/PanModalTests.swift | 1 - 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/PanModal/Controller/PanModalPresentationController.swift b/PanModal/Controller/PanModalPresentationController.swift index 1df3663..734c076 100644 --- a/PanModal/Controller/PanModalPresentationController.swift +++ b/PanModal/Controller/PanModalPresentationController.swift @@ -414,7 +414,6 @@ private extension PanModalPresentationController { to avoid visual bugs */ scrollView.showsVerticalScrollIndicator = false - scrollView.isScrollEnabled = presentable?.isPanScrollEnabled ?? true scrollView.scrollIndicatorInsets = presentable?.scrollIndicatorInsets ?? .zero /** @@ -444,8 +443,7 @@ private extension PanModalPresentationController { @objc func didPanOnPresentedView(_ recognizer: UIPanGestureRecognizer) { guard - presentable?.isPanScrollEnabled == true, - !shouldFail(panGestureRecognizer: recognizer), + shouldRespond(to: panGestureRecognizer), let containerView = containerView else { recognizer.setTranslation(.zero, in: recognizer.view) @@ -515,6 +513,26 @@ private extension PanModalPresentationController { } } + /** + Determine if the pan modal should respond to the gesture recognizer. + + If the pan modal is already being dragged & the delegate returns false, ignore until + the recognizer is back to it's original state (.began) + + ⚠️ This is the only time we should be cancelling the pan modal gesture recognizer + */ + func shouldRespond(to panGestureRecognizer: UIPanGestureRecognizer) -> Bool { + guard + presentable?.shouldRespond(to: panGestureRecognizer) == true || + !(panGestureRecognizer.state == .began || panGestureRecognizer.state == .cancelled) + else { + panGestureRecognizer.isEnabled = false + panGestureRecognizer.isEnabled = true + return false + } + return !shouldFail(panGestureRecognizer: panGestureRecognizer) + } + /** Communicate intentions to presentable and adjust subviews in containerView */ diff --git a/PanModal/Presentable/PanModalPresentable+Defaults.swift b/PanModal/Presentable/PanModalPresentable+Defaults.swift index a956596..f052c6c 100644 --- a/PanModal/Presentable/PanModalPresentable+Defaults.swift +++ b/PanModal/Presentable/PanModalPresentable+Defaults.swift @@ -64,10 +64,6 @@ public extension PanModalPresentable where Self: UIViewController { return true } - var isPanScrollEnabled: Bool { - return true - } - var isUserInteractionEnabled: Bool { return true } @@ -84,7 +80,11 @@ public extension PanModalPresentable where Self: UIViewController { return shouldRoundTopCorners } - func willRespond(to panGestureRecognizer: UIPanGestureRecognizer) { + func shouldRespond(to panModalGestureRecognizer: UIPanGestureRecognizer) -> Bool { + return true + } + + func willRespond(to panModalGestureRecognizer: UIPanGestureRecognizer) { } diff --git a/PanModal/Presentable/PanModalPresentable.swift b/PanModal/Presentable/PanModalPresentable.swift index 5885a44..9c8319b 100644 --- a/PanModal/Presentable/PanModalPresentable.swift +++ b/PanModal/Presentable/PanModalPresentable.swift @@ -111,16 +111,6 @@ public protocol PanModalPresentable { */ var allowsDragToDismiss: Bool { get } - /** - A flag to determine if scrolling should be enabled on the entire view. - - - Note: Returning false will disable scrolling on the embedded scrollview as well as on the - pan modal container view. - - Default value is true. - */ - var isPanScrollEnabled: Bool { get } - /** A flag to toggle user interactions on the container view. @@ -152,6 +142,15 @@ public protocol PanModalPresentable { */ var showDragIndicator: Bool { get } + /** + Asks the delegate if the pan modal should respond to the pan modal gesture recognizer. + + Return false to disable movement on the pan modal but maintain gestures on the presented view. + + Default value is true. + */ + func shouldRespond(to panModalGestureRecognizer: UIPanGestureRecognizer) -> Bool + /** Notifies the delegate when the pan modal gesture recognizer state is either `began` or `changed`. This method gives the delegate a chance to prepare diff --git a/Tests/PanModalTests.swift b/Tests/PanModalTests.swift index be6d387..3ff9cfa 100644 --- a/Tests/PanModalTests.swift +++ b/Tests/PanModalTests.swift @@ -53,7 +53,6 @@ class PanModalTests: XCTestCase { XCTAssertEqual(vc.anchorModalToLongForm, true) XCTAssertEqual(vc.allowsExtendedPanScrolling, false) XCTAssertEqual(vc.allowsDragToDismiss, true) - XCTAssertEqual(vc.isPanScrollEnabled, true) XCTAssertEqual(vc.isUserInteractionEnabled, true) XCTAssertEqual(vc.isHapticFeedbackEnabled, true) XCTAssertEqual(vc.shouldRoundTopCorners, false)