From d2f06462eefc409cb8fb020d11d0b0d8bfe3aa05 Mon Sep 17 00:00:00 2001 From: Anders Ha Date: Thu, 5 Apr 2018 16:26:18 +0100 Subject: [PATCH 1/2] Support modal presentation on top of the drawer. --- .../PresentationController+Animation.swift | 2 + .../PresentationController+Gestures.swift | 17 ++----- .../Internal API/PresentationController.swift | 13 +++-- .../PresentedViewController.swift | 4 ++ .../Storyboards/Base.lproj/Main.storyboard | 49 ++++++++++++++++++- 5 files changed, 66 insertions(+), 19 deletions(-) diff --git a/DrawerKit/DrawerKit/Internal API/PresentationController+Animation.swift b/DrawerKit/DrawerKit/Internal API/PresentationController+Animation.swift index b6d2a9b..44de2ec 100644 --- a/DrawerKit/DrawerKit/Internal API/PresentationController+Animation.swift +++ b/DrawerKit/DrawerKit/Internal API/PresentationController+Animation.swift @@ -85,6 +85,8 @@ extension PresentationController { self.currentDrawerCornerRadius = 0 } + self.targetDrawerState = endingState + AnimationSupport.clientCleanupViews(presentingDrawerAnimationActions: presentingAnimationActions, presentedDrawerAnimationActions: presentedAnimationActions, endingPosition, diff --git a/DrawerKit/DrawerKit/Internal API/PresentationController+Gestures.swift b/DrawerKit/DrawerKit/Internal API/PresentationController+Gestures.swift index 5d5dfb9..a730364 100644 --- a/DrawerKit/DrawerKit/Internal API/PresentationController+Gestures.swift +++ b/DrawerKit/DrawerKit/Internal API/PresentationController+Gestures.swift @@ -23,23 +23,15 @@ extension PresentationController { switch panGesture.state { case .began: - lastDrawerState = GeometryEvaluator.drawerState(for: currentDrawerY, - drawerPartialHeight: drawerPartialHeight, - containerViewHeight: containerViewHeight, - configuration: configuration, - clampToNearest: true) + break case .changed: - lastDrawerState = GeometryEvaluator.drawerState(for: currentDrawerY, - drawerPartialHeight: drawerPartialHeight, - containerViewHeight: containerViewHeight, - configuration: configuration, - clampToNearest: true) currentDrawerY += panGesture.translation(in: view).y + targetDrawerState = currentDrawerState currentDrawerCornerRadius = cornerRadius(at: currentDrawerState) panGesture.setTranslation(.zero, in: view) - case .ended: + case .ended, .cancelled: let drawerSpeedY = panGesture.velocity(in: view).y / containerViewHeight let endingState = GeometryEvaluator.nextStateFrom(currentState: currentDrawerState, speedY: drawerSpeedY, @@ -48,9 +40,6 @@ extension PresentationController { configuration: configuration) animateTransition(to: endingState) - case .cancelled: - animateTransition(to: lastDrawerState) - default: break } diff --git a/DrawerKit/DrawerKit/Internal API/PresentationController.swift b/DrawerKit/DrawerKit/Internal API/PresentationController.swift index 47cf651..e61ee54 100644 --- a/DrawerKit/DrawerKit/Internal API/PresentationController.swift +++ b/DrawerKit/DrawerKit/Internal API/PresentationController.swift @@ -11,7 +11,10 @@ final class PresentationController: UIPresentationController { var drawerFullExpansionTapGR: UITapGestureRecognizer? var drawerDismissalTapGR: UITapGestureRecognizer? var drawerDragGR: UIPanGestureRecognizer? - var lastDrawerState: DrawerState = .collapsed + + /// The target state of the drawer. If no presentation animation is in + /// progress, the value should be equivalent to `currentDrawerState`. + var targetDrawerState: DrawerState init(presentingVC: UIViewController?, presentingDrawerAnimationActions: DrawerAnimationActions, @@ -24,6 +27,11 @@ final class PresentationController: UIPresentationController { self.handleView = (configuration.handleViewConfiguration != nil ? UIView() : nil) self.presentingDrawerAnimationActions = presentingDrawerAnimationActions self.presentedDrawerAnimationActions = presentedDrawerAnimationActions + + // NOTE: Set the current drawer state to the target state of the initial + // presentation animation. + self.targetDrawerState = configuration.supportsPartialExpansion ? .partiallyExpanded : .fullyExpanded + super.init(presentedViewController: presentedVC, presenting: presentingVC) } } @@ -33,9 +41,8 @@ extension PresentationController { var frame: CGRect = .zero frame.size = size(forChildContentContainer: presentedViewController, withParentContainerSize: containerViewSize) - let state: DrawerState = (supportsPartialExpansion ? .partiallyExpanded : .fullyExpanded) let drawerFullY = configuration.fullExpansionBehaviour.drawerFullY - frame.origin.y = GeometryEvaluator.drawerPositionY(for: state, + frame.origin.y = GeometryEvaluator.drawerPositionY(for: targetDrawerState, drawerPartialHeight: drawerPartialHeight, containerViewHeight: containerViewHeight, drawerFullY: drawerFullY) diff --git a/DrawerKitDemo/DrawerKitDemo/PresentedViewController.swift b/DrawerKitDemo/DrawerKitDemo/PresentedViewController.swift index 4b2d306..7a95170 100644 --- a/DrawerKitDemo/DrawerKitDemo/PresentedViewController.swift +++ b/DrawerKitDemo/DrawerKitDemo/PresentedViewController.swift @@ -22,6 +22,10 @@ class PresentedViewController: UIViewController { } } } + + @IBAction func unwindFromModal(with segue: UIStoryboardSegue) { + print("Unwound from the modal.") + } } extension PresentedViewController: UIScrollViewDelegate { diff --git a/DrawerKitDemo/DrawerKitDemo/Storyboards/Base.lproj/Main.storyboard b/DrawerKitDemo/DrawerKitDemo/Storyboards/Base.lproj/Main.storyboard index 05dbe13..b49619d 100644 --- a/DrawerKitDemo/DrawerKitDemo/Storyboards/Base.lproj/Main.storyboard +++ b/DrawerKitDemo/DrawerKitDemo/Storyboards/Base.lproj/Main.storyboard @@ -1,11 +1,12 @@ - + - + + @@ -130,6 +131,12 @@ + @@ -137,12 +144,14 @@ + + @@ -163,6 +172,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + From 208dfbe5ddeb0a1d7f5b47736a9e59f5d6a8165f Mon Sep 17 00:00:00 2001 From: Anders Ha Date: Fri, 6 Apr 2018 13:49:28 +0100 Subject: [PATCH 2/2] Address comments regarding drag gesture handling. --- .../PresentationController+Gestures.swift | 11 +++++++++-- .../Internal API/PresentationController.swift | 2 ++ .../DrawerKitDemo/PresentedViewController.swift | 4 +--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/DrawerKit/DrawerKit/Internal API/PresentationController+Gestures.swift b/DrawerKit/DrawerKit/Internal API/PresentationController+Gestures.swift index a730364..452db63 100644 --- a/DrawerKit/DrawerKit/Internal API/PresentationController+Gestures.swift +++ b/DrawerKit/DrawerKit/Internal API/PresentationController+Gestures.swift @@ -23,7 +23,8 @@ extension PresentationController { switch panGesture.state { case .began: - break + startingDrawerStateForDrag = targetDrawerState + fallthrough case .changed: currentDrawerY += panGesture.translation(in: view).y @@ -31,7 +32,7 @@ extension PresentationController { currentDrawerCornerRadius = cornerRadius(at: currentDrawerState) panGesture.setTranslation(.zero, in: view) - case .ended, .cancelled: + case .ended: let drawerSpeedY = panGesture.velocity(in: view).y / containerViewHeight let endingState = GeometryEvaluator.nextStateFrom(currentState: currentDrawerState, speedY: drawerSpeedY, @@ -40,6 +41,12 @@ extension PresentationController { configuration: configuration) animateTransition(to: endingState) + case .cancelled: + if let startingState = startingDrawerStateForDrag { + startingDrawerStateForDrag = nil + animateTransition(to: startingState) + } + default: break } diff --git a/DrawerKit/DrawerKit/Internal API/PresentationController.swift b/DrawerKit/DrawerKit/Internal API/PresentationController.swift index e61ee54..1d841e8 100644 --- a/DrawerKit/DrawerKit/Internal API/PresentationController.swift +++ b/DrawerKit/DrawerKit/Internal API/PresentationController.swift @@ -16,6 +16,8 @@ final class PresentationController: UIPresentationController { /// progress, the value should be equivalent to `currentDrawerState`. var targetDrawerState: DrawerState + var startingDrawerStateForDrag: DrawerState? + init(presentingVC: UIViewController?, presentingDrawerAnimationActions: DrawerAnimationActions, presentedVC: UIViewController, diff --git a/DrawerKitDemo/DrawerKitDemo/PresentedViewController.swift b/DrawerKitDemo/DrawerKitDemo/PresentedViewController.swift index 7a95170..aed3072 100644 --- a/DrawerKitDemo/DrawerKitDemo/PresentedViewController.swift +++ b/DrawerKitDemo/DrawerKitDemo/PresentedViewController.swift @@ -23,9 +23,7 @@ class PresentedViewController: UIViewController { } } - @IBAction func unwindFromModal(with segue: UIStoryboardSegue) { - print("Unwound from the modal.") - } + @IBAction func unwindFromModal(with segue: UIStoryboardSegue) {} } extension PresentedViewController: UIScrollViewDelegate {