Skip to content

Commit 259dd7e

Browse files
committed
REFACTORING: Simplify DrawerConfiguration
1 parent 0db6d98 commit 259dd7e

File tree

3 files changed

+25
-23
lines changed

3 files changed

+25
-23
lines changed

Example/UIViewController-DisplayInDrawer/ContentViewController.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,21 @@ class ContentViewController: UIViewController {
6868
}
6969

7070
extension ContentViewController: DrawerConfiguration {
71-
func topPositionY(in parentFrame: CGRect) -> CGFloat {
71+
func topPositionY(for parentHeight: CGFloat) -> CGFloat {
7272
guard isViewLoaded else { return 0 }
7373
/*
7474
You can return constant, but this is a more dynamic example:
7575
How to avoid making the drawer unneccessarily larger than its content
7676
*/
7777
let minimalTopPosition: CGFloat = 50
78-
let idealTopPosition = parentFrame.height - contentDerivedHeight()
78+
let idealTopPosition = parentHeight - contentDerivedHeight()
7979
let result = fmax(minimalTopPosition, idealTopPosition)
8080
return result
8181
}
8282

83-
var bottomPositionHeight: CGFloat {
83+
func bottomPositionY(for parentHeight: CGFloat) -> CGFloat {
8484
guard isViewLoaded else { return 0 }
85-
return separatorView.frame.minY
85+
return parentHeight - separatorView.frame.minY
8686
}
8787

8888
func setPanGestureTarget(_ target: Any, action: Selector) {

UIViewController-DisplayInDrawer/Classes/PanGestureTarget.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ final class PanGestureTarget {
2424
private weak var drawerConfiguration: DrawerConfiguration?
2525
private weak var drawerPositionDelegate: DrawerPositionDelegate?
2626
private var initialDrawerCenterLocation: CGPoint = .zero
27-
private var bottomPositionHeight: CGFloat!
28-
var basePositionY: CGFloat { return canvasView.frame.height - bottomPositionHeight }
27+
var basePositionY: CGFloat!
2928
var topPositionY: CGFloat!
3029

3130
init(canvasView: UIView,
@@ -42,8 +41,8 @@ final class PanGestureTarget {
4241
}
4342

4443
internal func refreshDrawerPositions() {
45-
bottomPositionHeight = drawerConfiguration?.bottomPositionHeight ?? 0
46-
topPositionY = drawerConfiguration?.topPositionY(in: canvasView.bounds) ?? 0
44+
basePositionY = drawerConfiguration?.bottomPositionY(for: canvasView.bounds.height) ?? 0
45+
topPositionY = drawerConfiguration?.topPositionY(for: canvasView.bounds.height) ?? 0
4746
}
4847

4948
deinit {
@@ -117,7 +116,7 @@ final class PanGestureTarget {
117116

118117
private func isInUpperHalfOfMovement() -> Bool {
119118
let allowedMovementMinY = topPositionY!
120-
let allowedMovementMaxY = basePositionY
119+
let allowedMovementMaxY = basePositionY!
121120
let halfMovement = (allowedMovementMaxY - allowedMovementMinY) / 2
122121
let movementMidY = allowedMovementMinY + halfMovement
123122
return drawerContainerView.frame.minY < movementMidY

UIViewController-DisplayInDrawer/Classes/UIViewController+PresentDrawerController.swift

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import UIKit
44

55
public protocol DrawerConfiguration: class {
6-
func topPositionY(in parentFrame: CGRect) -> CGFloat
7-
var bottomPositionHeight: CGFloat { get }
6+
func topPositionY(for parentHeight: CGFloat) -> CGFloat
7+
func bottomPositionY(for parentHeight: CGFloat) -> CGFloat
88
/**
99
drawerDismissClosure is injected by this lib.
1010
You should not change it, and you should call it when user presses dismiss button in your content view controller.
@@ -84,7 +84,7 @@ extension UIViewController {
8484
return { [weak self, weak containerView, weak initialDisplayAnimator] in
8585
guard let strongSelf = self, let strongContainerView = containerView else { return }
8686
let oldTopPositionY = panGestureTarget.topPositionY!
87-
let oldBasePositionY = panGestureTarget.basePositionY
87+
let oldBasePositionY = panGestureTarget.basePositionY!
8888
panGestureTarget.refreshDrawerPositions()
8989
let newContainerHeight = strongSelf.view.bounds.height - panGestureTarget.topPositionY + bottomOverpullPaddingHeight
9090
if strongContainerView.frame.height != newContainerHeight {
@@ -97,15 +97,18 @@ extension UIViewController {
9797
let newTopPositionIsDifferentThanOld = Int(panGestureTarget.topPositionY) != Int(oldTopPositionY)
9898
let isOnOldBottomPosition = Int(strongContainerView.frame.minY) == Int(oldBasePositionY)
9999
let newBottomPositionIsDifferentThanOld = Int(panGestureTarget.basePositionY) != Int(oldBasePositionY)
100-
if isOnOldTopPosition && newTopPositionIsDifferentThanOld {
101-
self?.updateWithNewYPosition(panGestureTarget.topPositionY,
102-
containerView: strongContainerView,
103-
inFlightAnimator: initialDisplayAnimator
100+
let isInitialDisplayAnimation = initialDisplayAnimator != nil
101+
if !isInitialDisplayAnimation && isOnOldTopPosition && newTopPositionIsDifferentThanOld {
102+
self?.updateDrawerPosition(
103+
inFlightAnimator: initialDisplayAnimator,
104+
newTargetY: panGestureTarget.topPositionY,
105+
containerView: strongContainerView
104106
)
105107
} else if isOnOldBottomPosition && newBottomPositionIsDifferentThanOld {
106-
self?.updateWithNewYPosition(panGestureTarget.basePositionY,
107-
containerView: strongContainerView,
108-
inFlightAnimator: initialDisplayAnimator
108+
self?.updateDrawerPosition(
109+
inFlightAnimator: initialDisplayAnimator,
110+
newTargetY: panGestureTarget.basePositionY,
111+
containerView: strongContainerView
109112
)
110113
}
111114
}
@@ -122,10 +125,10 @@ extension UIViewController {
122125
controller.didMove(toParentViewController: self)
123126
}
124127

125-
private func updateWithNewYPosition(_ newY: CGFloat, containerView: UIView, inFlightAnimator: UIViewPropertyAnimator?) {
128+
private func updateDrawerPosition(inFlightAnimator: UIViewPropertyAnimator?, newTargetY: CGFloat, containerView: UIView) {
126129
dLog("inFlightAnimator: \(String(describing: inFlightAnimator))")
127130
var newFrame = containerView.frame
128-
newFrame.origin.y = newY
131+
newFrame.origin.y = newTargetY
129132
if let animator = inFlightAnimator {
130133
animator.addAnimations { containerView.frame = newFrame }
131134
} else {
@@ -137,7 +140,7 @@ extension UIViewController {
137140
containerView: UIView,
138141
positionDelegate: DrawerPositionDelegate?) -> UIViewPropertyAnimator {
139142
var endFrame = containerView.frame
140-
endFrame.origin.y = view.bounds.height - drawerConfiguration.bottomPositionHeight
143+
endFrame.origin.y = drawerConfiguration.bottomPositionY(for: view.bounds.height)
141144
let animator = UIViewPropertyAnimator(duration: 0.25, curve: .easeInOut, animations: {
142145
containerView.frame = endFrame
143146
})
@@ -184,7 +187,7 @@ extension UIViewController {
184187
private extension UIView {
185188
func addContainerView(for drawerConfiguration: DrawerConfiguration, cornerRadius: CGFloat, bottomPaddingHeight: CGFloat) -> UIView {
186189
var startFrame = bounds
187-
startFrame.size.height = bounds.height - drawerConfiguration.topPositionY(in: bounds) + bottomPaddingHeight
190+
startFrame.size.height = bounds.height - drawerConfiguration.topPositionY(for: bounds.height) + bottomPaddingHeight
188191
startFrame.origin.y += bounds.height
189192
let containerView = UIView(frame: startFrame)
190193
containerView.preservesSuperviewLayoutMargins = true

0 commit comments

Comments
 (0)