- April 27, 2024
- Mins Read
A library to imitate the drawer in Maps for iOS 10/11. The master branch follows the latest currently released version of Swift. If you need an older version of Swift, you can specify it’s version (e.g. 1.0.x) in your Podfile or use the code on the branch for that version. Older branches are unsupported.
ATTENTION: Pulley 2.9.0 has new properties to support a new displayMode. The base functionality should work without any significant changes. The biggest change being the new displayMode of .compact
to replicate Apple Maps Behavior on the iPhone SE size class devices. This is an exact replica of the behavior of the Apple Maps drawer, therefor when the currentDisplayMode
of the PulleyViewController
is .compact
then the only supportedDrawerPositions
for the view controller when in .compact
mode are .open
, .closed
, and .collapsed
. This mode also has new @IBInspectable properties, compactInsets
and compactWidth
. This mode behaves in a very similar way to .panel
mode. See the pull request here for the motivation behind this feature. Also in this release, setDrawerContentViewController(controller: UIViewController, position: PulleyPosition? = nil, animated: Bool = true, completion: PulleyAnimationCompletionBlock?)
has a new optional parameter position
to set a new drawer position the drawer when a new DrawerContentViewController
is set. See this pull request for the motivation behind this feature.
Pulley 2.5.0 had significant renaming changes to support new features. Although property names have changed, the functionality should work without any significant changes (aside from renaming). See this thread for additional information.
Pulley 2.4.0 changed PulleyPosition from an enum to a class. This won’t affect most uses, but may affect your switch statements. Continue to use the static PulleyPosition values as usual and add a default case. This was done to allow marking some PulleyDrawerViewControllerDelegate
methods as optional so they don’t need to be implemented if you aren’t using certain positions (or wish to use the default values). If you have questions, please open an issue.
Technical reason: Optional protocol methods require the @objc attribute. Arrays of Swift enums can’t be exposed to Objective-C, and supportedDrawerPositions previously returned an array of PulleyPosition enums. This change allows for marking the protocol @objc so methods can be marked optional.
Pulley is an easy to use drawer library meant to imitate the drawer in iOS 10/11’s Maps app. It exposes a simple API that allows you to use any UIViewController subclass as the drawer content or the primary content.
Here’s a preview (apologies for the potato gif):
pod 'Pulley'
github "52inc/Pulley"
Please read this issue regarding setup if using Carthage.
Follow the developer documentation for Swift Package Manager (versions 2.8.x)
Simply copy the files in the PulleyLib folder into your project.
Pulley supports loading embedded view controllers from Interface Builder. In order to use Pulley with Interface Builder, you’ll need to setup your PulleyViewController
like this:
PulleyViewController
view. One for the drawer content and one for the primary (background) content.If you would like to customize the height of the “Collapsed” or “Partially Revealed” states of the drawer, have your Drawer Content view controller implement PulleyDrawerViewControllerDelegate
. You can provide the height for your drawer content for both the Collapsed and Partially Revealed states.
Pulley supports loading view controllers programmatically. In order to use Pulley programmatically, please consider the following code snippet:
let mainContentVC = UIStoryboard(name: “Main”, bundle: nil).instantiateViewControllerWithIdentifier(“PrimaryContentViewController”)
let drawerContentVC = UIStoryboard(name: “Main”, bundle: nil).instantiateViewControllerWithIdentifier(“DrawerContentViewController”)
let pulleyController = PulleyViewController(contentViewController: mainContentVC, drawerViewController: drawerContentVC)
self.pulleyViewController
until during or after -viewWillAppear: if you’re loading Pulley from Storyboards.Pulley has support for safe areas and the iPhone X. The sample project includes full support for this, and does a couple of UI tricks to make things look better. These are documented throughout the sample project.
The basic concepts of using Pulley post-iOS 11 are:
drawerPositionDidChange(drawer:bottomSafeArea:)
to modify your UI based on the value of bottomSafeArea. Any time the size of the Pulley view controller changes, this method will be called with a new bottom safe area height. The sample project uses this to modify the drawer ‘header’ height, as well as to adjust the contentInset for the UITableView. It’s not automatically taken care of for you, but it should be a fairly simple thing to add.If you have any problems / questions while updating Pulley to iOS 11 SDK, please feel free to create an issue if the above information didn’t solve your problem.
Even if you’ve already seen the example project, I highly encourage looking at the new post-iOS 11 version of the sample project. It may have something that could help your iPhone X / safe area implementation.
PulleyDelegate
: The protocol the other protocols inherit from. It’s exposed as the .delegate property of PulleyViewController
. NOTE: If the object you’re wanting to receive delegate callbacks is either the Primary Content or Drawer Content view controllers…don’t use the .delegate property. Continue reading for the other protocols.PulleyDrawerViewControllerDelegate
: Includes all of the methods from PulleyDelegate
and adds methods for providing custom heights for the Collapsed and Partially Revealed states. Your Drawer Content view controller should implement this protocol if it wants to receive callbacks for changes in the drawer state or to provide custom heights for the aforementioned drawer states. Implementing this protocol is optional for the Drawer Content view controller, but if you don’t then defaults will be used instead.PulleyPrimaryContentControllerDelegate
: This is currently identical to PulleyDelegate
. However, this protocol may be implemented by your Primary Content view controller if you want to receive callbacks for changes in drawer state. Eventually specialized methods may be added to this protocol.You’ll likely need to change out the contents of the drawer or the primary view controller after creation. Here’s how to do that programmatically.
if let drawer = self.parentViewController as? PulleyViewController
{
let primaryContent = UIStoryboard(name: “Main”, bundle: nil).instantiateViewControllerWithIdentifier(“PrimaryContentViewController”)
drawer.setPrimaryContentViewController(primaryContent, animated: true)
}
if let drawer = self.parentViewController as? PulleyViewController
{
let drawerContent = UIStoryboard(name: “Main”, bundle: nil).instantiateViewControllerWithIdentifier(“DrawerContentViewController”)
drawer.setDrawerContentViewController(drawerContent, animated: false)
}
PulleyViewController
.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.PulleyViewController
.PulleyViewController
.PulleyViewController
.PulleyViewController
.PulleyViewController
.PulleyViewController
.PulleyViewController
.PulleyViewController
.PulleyViewController
is documented in case you want to see real documentation instead of a numbered list of useful things.PulleyViewController
.PulleyViewController
are exposed in Interface Builder. Select the PulleyViewController
View Controller (not the view) to access them via IBInspectable.Horizon SDK is a state of the art real-time video recording / photo shooting iOS library. Some of the features ...