Skip to content

Commit

Permalink
Merge pull request #14 from 52inc/feature/supported-drawer-stops
Browse files Browse the repository at this point in the history
Feature/supported drawer stops
  • Loading branch information
amyleecodes authored Sep 27, 2016
2 parents 65916f0 + d8a6cdc commit fea40e6
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 25 deletions.
4 changes: 4 additions & 0 deletions Pulley/DrawerContentViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ class DrawerContentViewController: UIViewController, UITableViewDelegate, UITabl
{
return 264.0
}

func supportedDrawerPositions() -> [PulleyPosition] {
return PulleyPosition.all // You can specify the drawer positions you support. This is the same as: [.open, .partiallyRevealed, .collapsed]
}

func drawerPositionDidChange(drawer: PulleyViewController)
{
Expand Down
141 changes: 125 additions & 16 deletions PulleyLib/PulleyViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@ import UIKit
/**
* View controllers in the drawer can implement this to receive changes in state or provide values for the different drawer positions.
*/
@objc public protocol PulleyDrawerViewControllerDelegate: PulleyDelegate {
public protocol PulleyDrawerViewControllerDelegate: PulleyDelegate {

func collapsedDrawerHeight() -> CGFloat
func partialRevealDrawerHeight() -> CGFloat
func supportedDrawerPositions() -> [PulleyPosition]
}

/**
* View controllers that are the main content can implement this to receive changes in state.
*/
@objc public protocol PulleyPrimaryContentControllerDelegate: PulleyDelegate {
public protocol PulleyPrimaryContentControllerDelegate: PulleyDelegate {

// Not currently used for anything, but it's here for parity with the hopes that it'll one day be used.
}
Expand All @@ -42,11 +43,17 @@ import UIKit
- partiallyRevealed: When the drawer is partially revealed.
- open: When the drawer is fully open.
*/
public enum PulleyPosition {
public enum PulleyPosition: Int {

case collapsed
case partiallyRevealed
case open
case collapsed = 0
case partiallyRevealed = 1
case open = 2

static var all: [PulleyPosition] = [
.collapsed,
.partiallyRevealed,
.open
]
}

private let kPulleyDefaultCollapsedHeight: CGFloat = 68.0
Expand All @@ -72,7 +79,7 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP
private var dimmingViewTapRecognizer: UITapGestureRecognizer?

/// The current content view controller (shown behind the drawer).
private(set) var primaryContentViewController: UIViewController! {
public fileprivate(set) var primaryContentViewController: UIViewController! {
willSet {

guard let controller = primaryContentViewController else {
Expand All @@ -97,12 +104,13 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP
if self.isViewLoaded
{
self.view.setNeedsLayout()
self.setNeedsSupportedDrawerPositionsUpdate()
}
}
}

/// The current drawer view controller (shown in the drawer).
private(set) var drawerContentViewController: UIViewController! {
public fileprivate(set) var drawerContentViewController: UIViewController! {
willSet {

guard let controller = drawerContentViewController else {
Expand All @@ -127,6 +135,7 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP
if self.isViewLoaded
{
self.view.setNeedsLayout()
self.setNeedsSupportedDrawerPositionsUpdate()
}
}
}
Expand All @@ -135,7 +144,7 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP
public weak var delegate: PulleyDelegate?

/// The current position of the drawer.
public private(set) var drawerPosition: PulleyPosition = .collapsed {
public fileprivate(set) var drawerPosition: PulleyPosition = .collapsed {
didSet {
setNeedsStatusBarAppearanceUpdate()
}
Expand Down Expand Up @@ -219,6 +228,38 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP
}
}

/// The drawer positions supported by the drawer
fileprivate var supportedDrawerPositions: [PulleyPosition] = PulleyPosition.all {
didSet {

guard self.isViewLoaded else {
return
}

guard supportedDrawerPositions.count > 0 else {
supportedDrawerPositions = PulleyPosition.all
return
}

self.view.setNeedsLayout()

if supportedDrawerPositions.contains(drawerPosition)
{
setDrawerPosition(position: drawerPosition)
}
else
{
let lowestDrawerState: PulleyPosition = supportedDrawerPositions.min { (pos1, pos2) -> Bool in
return pos1.rawValue < pos2.rawValue
} ?? .collapsed

setDrawerPosition(position: lowestDrawerState, animated: false)
}

drawerScrollView.isScrollEnabled = supportedDrawerPositions.count > 1
}
}

/**
Initialize the drawer controller programmtically.

Expand Down Expand Up @@ -341,15 +382,19 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP
scrollViewDidScroll(drawerScrollView)
}

override open func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

setNeedsSupportedDrawerPositionsUpdate()
}

override open func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()

// Layout main content
primaryContentContainer.frame = self.view.bounds
backgroundDimmingView.frame = self.view.bounds

// Layout scrollview
drawerScrollView.frame = CGRect(x: 0, y: topInset, width: self.view.bounds.width, height: self.view.bounds.height - topInset)

// Layout container
var collapsedHeight:CGFloat = kPulleyDefaultCollapsedHeight
Expand All @@ -363,6 +408,19 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP

let lowestStop = [(self.view.bounds.size.height - topInset), collapsedHeight, partialRevealHeight].min() ?? 0
let bounceOverflowMargin: CGFloat = 20.0

if supportedDrawerPositions.contains(.open)
{
// Layout scrollview
drawerScrollView.frame = CGRect(x: 0, y: topInset, width: self.view.bounds.width, height: self.view.bounds.height - topInset)
}
else
{
// Layout scrollview
let adjustedTopInset: CGFloat = supportedDrawerPositions.contains(.partiallyRevealed) ? partialRevealHeight : collapsedHeight
drawerScrollView.frame = CGRect(x: 0, y: self.view.bounds.height - adjustedTopInset, width: self.view.bounds.width, height: adjustedTopInset)
}

drawerContentContainer.frame = CGRect(x: 0, y: drawerScrollView.bounds.height - lowestStop, width: drawerScrollView.bounds.width, height: drawerScrollView.bounds.height + bounceOverflowMargin)
drawerBackgroundVisualEffectView?.frame = drawerContentContainer.frame
drawerShadowView.frame = drawerContentContainer.frame
Expand Down Expand Up @@ -399,6 +457,10 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP
*/
public func setDrawerPosition(position: PulleyPosition, animated: Bool = true)
{
guard supportedDrawerPositions.contains(position) else {
return
}

drawerPosition = position

var collapsedHeight:CGFloat = kPulleyDefaultCollapsedHeight
Expand Down Expand Up @@ -500,6 +562,21 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP
}
}

/**
Update the supported drawer positions allows by the Pulley Drawer
*/
public func setNeedsSupportedDrawerPositionsUpdate()
{
if let drawerVCCompliant = drawerContentViewController as? PulleyDrawerViewControllerDelegate
{
supportedDrawerPositions = drawerVCCompliant.supportedDrawerPositions()
}
else
{
supportedDrawerPositions = PulleyPosition.all
}
}

// MARK: Actions

func dimmingViewTapRecognizerAction(gestureRecognizer: UITapGestureRecognizer)
Expand Down Expand Up @@ -531,7 +608,23 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP
partialRevealHeight = drawerVCCompliant.partialRevealDrawerHeight()
}

let drawerStops = [(self.view.bounds.size.height - topInset), collapsedHeight, partialRevealHeight]
var drawerStops: [CGFloat] = [CGFloat]()

if supportedDrawerPositions.contains(.open)
{
drawerStops.append((self.view.bounds.size.height - topInset))
}

if supportedDrawerPositions.contains(.partiallyRevealed)
{
drawerStops.append(partialRevealHeight)
}

if supportedDrawerPositions.contains(.collapsed)
{
drawerStops.append(collapsedHeight)
}

let lowestStop = drawerStops.min() ?? 0

let distanceFromBottomOfView = lowestStop + lastDragTargetContentOffset.y
Expand All @@ -546,13 +639,13 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP
}
}

if abs(Float(currentClosestStop - (self.view.bounds.size.height - topInset))) <= FLT_EPSILON
if abs(Float(currentClosestStop - (self.view.bounds.size.height - topInset))) <= FLT_EPSILON && supportedDrawerPositions.contains(.open)
{
setDrawerPosition(position: .open, animated: true)
} else if abs(Float(currentClosestStop - collapsedHeight)) <= FLT_EPSILON
} else if abs(Float(currentClosestStop - collapsedHeight)) <= FLT_EPSILON && supportedDrawerPositions.contains(.collapsed)
{
setDrawerPosition(position: .collapsed, animated: true)
} else {
} else if supportedDrawerPositions.contains(.partiallyRevealed){
setDrawerPosition(position: .partiallyRevealed, animated: true)
}
}
Expand Down Expand Up @@ -582,7 +675,23 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP
partialRevealHeight = drawerVCCompliant.partialRevealDrawerHeight()
}

let drawerStops = [(self.view.bounds.size.height - topInset), collapsedHeight, partialRevealHeight]
var drawerStops: [CGFloat] = [CGFloat]()

if supportedDrawerPositions.contains(.open) || true
{
drawerStops.append((self.view.bounds.size.height - topInset))
}

if supportedDrawerPositions.contains(.partiallyRevealed) || true
{
drawerStops.append(partialRevealHeight)
}

if supportedDrawerPositions.contains(.collapsed) || true
{
drawerStops.append(collapsedHeight)
}

let lowestStop = drawerStops.min() ?? 0

if scrollView.contentOffset.y > partialRevealHeight - lowestStop
Expand Down
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,13 @@ if let drawer = self.parentViewController as? PulleyViewController

1. See the 3 protocols above.
2. You can adjust the inset from the top of the screen in the "Open" state by setting the -topInset property on the `PulleyViewController`.
3. You can adjust the corner radius applied to the drawer by setting the -drawerCornerRadius property on the `PulleyViewController`.
4. You can adjust the shadow opacity applied to the drawer by setting the -shadowOpacity property on the `PulleyViewController`.
5. You can adjust the shadow radius applied to the drawer by setting the -shadowRadius property on the `PulleyViewController`.
6. You can adjust the background dimming color by setting the -backgroundDimmingColor to an opaque color on the `PulleyViewController`.
7. You can adjust / remove the background blur effect by setting the -drawerBackgroundVisualEffectView property on the `PulleyViewController`.
8. You can adjust the alpha of the background dimming color by setting the -backgroundDimmingOpacity property on the `PulleyViewController`.
9. You can change the drawer position by calling setDrawerPosition( : ) on the `PulleyViewController`.
10. If an object needs to receive delegate callbacks and _isn't_ one of the view controller's presented then you can use the -delegate property on the `PulleyViewController`.
11. The Swift Interface for `PulleyViewController` is documented in case you want to see real documentation instead of a numbered list of useful things.
3. You can enable / disable drawer positions by implementing `PulleyDrawerViewControllerDelegate` in your 'drawer' view controller. If you need to change it, call `setNeedsSupportedDrawerPositionsUpdate()` on the `PulleyViewController` so it will recalculate the drawer based on your new settings.
4. You can adjust the corner radius applied to the drawer by setting the -drawerCornerRadius property on the `PulleyViewController`.
5. You can adjust the shadow opacity applied to the drawer by setting the -shadowOpacity property on the `PulleyViewController`.
6. You can adjust the shadow radius applied to the drawer by setting the -shadowRadius property on the `PulleyViewController`.
7. You can adjust the background dimming color by setting the -backgroundDimmingColor to an opaque color on the `PulleyViewController`.
8. You can adjust / remove the background blur effect by setting the -drawerBackgroundVisualEffectView property on the `PulleyViewController`.
9. You can adjust the alpha of the background dimming color by setting the -backgroundDimmingOpacity property on the `PulleyViewController`.
10. You can change the drawer position by calling setDrawerPosition( : ) on the `PulleyViewController`.
11. If an object needs to receive delegate callbacks and _isn't_ one of the view controller's presented then you can use the -delegate property on the `PulleyViewController`.
12. The Swift Interface for `PulleyViewController` is documented in case you want to see real documentation instead of a numbered list of useful things.

0 comments on commit fea40e6

Please sign in to comment.