From c7024330494b1653826931ee1e5fee20feb70437 Mon Sep 17 00:00:00 2001 From: Brendan Lee Date: Tue, 25 Oct 2016 22:14:18 -0400 Subject: [PATCH] IBInspectable support for PullerDrawerViewController settings. Formally added / fixed edge cases for 'closed' drawer position. Added "initialDrawerPosition" option so the drawer starts in the position you'd like. Added a programmatic example for initialDrawerPosition in AppDelegate. --- Pulley/AppDelegate.swift | 15 ++++-- Pulley/DrawerContentViewController.swift | 2 +- PulleyLib/PulleyViewController.swift | 66 ++++++++++++++++++++---- 3 files changed, 67 insertions(+), 16 deletions(-) diff --git a/Pulley/AppDelegate.swift b/Pulley/AppDelegate.swift index b5954e0..ab46ce3 100644 --- a/Pulley/AppDelegate.swift +++ b/Pulley/AppDelegate.swift @@ -22,10 +22,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // To create from a Storyboard window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()! - // To create in code (uncomment next 3 lines) -// let mainContentVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("PrimaryContentViewController") -// let drawerContentVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("DrawerContentViewController") -// window?.rootViewController = PulleyViewController(contentViewController: mainContentVC, drawerViewController: drawerContentVC) + // To create in code (uncomment this block) + /* + let mainContentVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PrimaryContentViewController") + let drawerContentVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DrawerContentViewController") + let pulleyDrawerVC = PulleyViewController(contentViewController: mainContentVC, drawerViewController: drawerContentVC) + + // Uncomment this next line to give the drawer a starting position, in this case: closed. + // pulleyDrawerVC.initialDrawerPosition = .closed + + window?.rootViewController = pulleyDrawerVC + */ window?.makeKeyAndVisible() diff --git a/Pulley/DrawerContentViewController.swift b/Pulley/DrawerContentViewController.swift index ead5e2a..34eea5b 100644 --- a/Pulley/DrawerContentViewController.swift +++ b/Pulley/DrawerContentViewController.swift @@ -72,7 +72,7 @@ class DrawerContentViewController: UIViewController, UITableViewDelegate, UITabl } func supportedDrawerPositions() -> [PulleyPosition] { - return PulleyPosition.all // You can specify the drawer positions you support. This is the same as: [.open, .partiallyRevealed, .collapsed] + return PulleyPosition.all // You can specify the drawer positions you support. This is the same as: [.open, .partiallyRevealed, .collapsed, .closed] } func drawerPositionDidChange(drawer: PulleyViewController) diff --git a/PulleyLib/PulleyViewController.swift b/PulleyLib/PulleyViewController.swift index 2b1eedb..88ca01a 100644 --- a/PulleyLib/PulleyViewController.swift +++ b/PulleyLib/PulleyViewController.swift @@ -42,6 +42,7 @@ public protocol PulleyPrimaryContentControllerDelegate: PulleyDelegate { - collapsed: When the drawer is in its smallest form, at the bottom of the screen. - partiallyRevealed: When the drawer is partially revealed. - open: When the drawer is fully open. + - closed: When the drawer is off-screen at the bottom of the view. Note: Users cannot close or reopen the drawer on their own. You must set this programatically */ public enum PulleyPosition: Int { @@ -56,6 +57,33 @@ public enum PulleyPosition: Int { .open, .closed ] + + public static func positionFor(string: String?) -> PulleyPosition { + + guard let positionString = string?.lowercased() else { + + return .collapsed + } + + switch positionString { + + case "collapsed": + return .collapsed + + case "partiallyrevealed": + return .partiallyRevealed + + case "open": + return .open + + case "closed": + return .closed + + default: + print("PulleyViewController: Position for string '\(positionString)' not found. Available values are: collapsed, partiallyRevealed, open, and closed. Defaulting to collapsed.") + return .collapsed + } + } } private let kPulleyDefaultCollapsedHeight: CGFloat = 68.0 @@ -66,10 +94,10 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP // Interface Builder /// When using with Interface Builder only! Connect a containing view to this outlet. - @IBOutlet var primaryContentContainerView: UIView! + @IBOutlet public var primaryContentContainerView: UIView! /// When using with Interface Builder only! Connect a containing view to this outlet. - @IBOutlet var drawerContentContainerView: UIView! + @IBOutlet public var drawerContentContainerView: UIView! // Internal private let primaryContentContainer: UIView = UIView() @@ -169,7 +197,7 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP } /// The inset from the top of the view controller when fully open. - public var topInset: CGFloat = 50.0 { + @IBInspectable public var topInset: CGFloat = 50.0 { didSet { if self.isViewLoaded { @@ -179,7 +207,7 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP } /// The corner radius for the drawer. - public var drawerCornerRadius: CGFloat = 13.0 { + @IBInspectable public var drawerCornerRadius: CGFloat = 13.0 { didSet { if self.isViewLoaded { @@ -190,7 +218,7 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP } /// The opacity of the drawer shadow. - public var shadowOpacity: Float = 0.1 { + @IBInspectable public var shadowOpacity: Float = 0.1 { didSet { if self.isViewLoaded { @@ -200,7 +228,7 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP } /// The radius of the drawer shadow. - public var shadowRadius: CGFloat = 3.0 { + @IBInspectable public var shadowRadius: CGFloat = 3.0 { didSet { if self.isViewLoaded { @@ -210,7 +238,7 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP } /// The opaque color of the background dimming view. - public var backgroundDimmingColor: UIColor = UIColor.black { + @IBInspectable public var backgroundDimmingColor: UIColor = UIColor.black { didSet { if self.isViewLoaded { @@ -220,7 +248,7 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP } /// The maximum amount of opacity when dimming. - public var backgroundDimmingOpacity: CGFloat = 0.5 { + @IBInspectable public var backgroundDimmingOpacity: CGFloat = 0.5 { didSet { if self.isViewLoaded @@ -230,6 +258,16 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP } } + /// The starting position for the drawer when it first loads + public var initialDrawerPosition: PulleyPosition = .collapsed + + /// This is here exclusively to support IBInspectable in Interface Builder because Interface Builder can't deal with enums. If you're doing this in code use the -initialDrawerPosition property instead. Available strings are: open, closed, partiallyRevealed, collapsed + @IBInspectable public var initialDrawerPositionFromIB: String? { + didSet { + initialDrawerPosition = PulleyPosition.positionFor(string: initialDrawerPositionFromIB) + } + } + /// The drawer positions supported by the drawer fileprivate var supportedDrawerPositions: [PulleyPosition] = PulleyPosition.all { didSet { @@ -381,6 +419,8 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP assert(primaryContentViewController != nil && drawerContentViewController != nil, "Container views must contain an embedded view controller.") } + setDrawerPosition(position: initialDrawerPosition, animated: false) + scrollViewDidScroll(drawerScrollView) } @@ -442,6 +482,8 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP // Make VC views match frames primaryContentViewController?.view.frame = primaryContentContainer.bounds drawerContentViewController?.view.frame = CGRect(x: drawerContentContainer.bounds.minX, y: drawerContentContainer.bounds.minY, width: drawerContentContainer.bounds.width, height: drawerContentContainer.bounds.height) + + setDrawerPosition(position: drawerPosition, animated: false) } override open func didReceiveMemoryWarning() { @@ -460,6 +502,8 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP public func setDrawerPosition(position: PulleyPosition, animated: Bool = true) { guard supportedDrawerPositions.contains(position) else { + + print("PulleyViewController: You can't set the drawer position to something not supported by the current view controller contained in the drawer. If you haven't already, you may need to implement the PulleyDrawerViewControllerDelegate.") return } @@ -682,17 +726,17 @@ open class PulleyViewController: UIViewController, UIScrollViewDelegate, PulleyP var drawerStops: [CGFloat] = [CGFloat]() - if supportedDrawerPositions.contains(.open) || true + if supportedDrawerPositions.contains(.open) { drawerStops.append((self.view.bounds.size.height - topInset)) } - if supportedDrawerPositions.contains(.partiallyRevealed) || true + if supportedDrawerPositions.contains(.partiallyRevealed) { drawerStops.append(partialRevealHeight) } - if supportedDrawerPositions.contains(.collapsed) || true + if supportedDrawerPositions.contains(.collapsed) { drawerStops.append(collapsedHeight) }