Pull up controller with multiple sticky points like in iOS Maps

Overview

PullUpController

Create your own pull up controller with multiple sticky points like in iOS Maps

Platform Swift 5 Cocoapods Compatible Maintainability

Features

  • Multiple sticky points
  • Landscape support
  • Scroll views friendly

Setup

  1. Add pod 'PullUpController' to your Podfile or copy PullUpController.swift into your project
  2. Make sure the view controller that will be your pull up controller inherits from PullUpController
  3. Add the controller as child of your main controller using addPullUpController(<#T##PullUpController#>, initialStickyPointOffset: <#T##CGFloat#>, animated: <#T##Bool#>)

Customization

You can customize the controller behavior by overriding the followings properties:

pullUpControllerPreferredSize: CGSize

The desired size of the pull up controller’s view, in screen units. The default value is width: UIScreen.main.bounds.width, height: 400.

pullUpControllerPreferredLandscapeFrame: CGRect

The desired size of the pull up controller’s view, in screen units when the device is in landscape mode. The default value is (x: 10, y: 10, width: 300, height: UIScreen.main.bounds.height - 20).

pullUpControllerMiddleStickyPoints: [CGFloat]

A list of y values, in screen units expressed in the pull up controller coordinate system. At the end of the gestures the pull up controller will scroll to the nearest point in the list.

For a complete list of all the sticky points you can use pullUpControllerAllStickyPoints

pullUpControllerBounceOffset: CGFloat

A CGFloat value that determines how much the pull up controller's view can bounce outside it's size. The default value is 0 and that means the the view cannot expand beyond its size.

It's possible to change the view controller's view position programmatically by using the method pullUpControllerMoveToVisiblePoint(_ visiblePoint: CGFloat, animated: Bool, completion: (() -> Void)?)

This method will move the pull up controller's view in order to show the provided visible point.

You may use on of pullUpControllerAllStickyPoints item to provide a valid visible point.

  • visiblePoint: the y value to make visible, in screen units expressed in the pull up controller coordinate system.
  • animated: a true value will move the view with an animation.
  • completion: the closure to execute after the animation is completed. This block has no return value and takes no parameters. You may specify nil for this parameter.

By overriding the following method it is possible to customize all the animations performed by the controller's view. pullUpControllerAnimate(action: Action, withDuration duration: TimeInterval, animations: @escaping () -> Void, completion: ((Bool) -> Void)?)

You can consider override this method and customize the animation using the method UIView.animate(withDuration:, delay:, usingSpringWithDamping:, initialSpringVelocity:, options:, animations:, completion:)

  • parameter: The action that is about to be performed (.add, .remove or .move)
  • duration: The total duration of the animations, measured in seconds. If you specify a negative value or 0, the changes are made without animating them. -animations: A block object containing the changes to commit to the views. completion: A block object to be executed when the animation sequence ends.

It is possible to observe the PullUpController's view state by overriding those methods: pullUpControllerWillMove(to point: CGFloat)

This method is called before the pull up controller's view move to a sticky point.

pullUpControllerDidMove(to point: CGFloat)

This method is called after the pull up controller's view move to a point.

pullUpControllerDidDrag(to point: CGFloat)

This method is called after the pull up controller's view is dragged to a point.

PullUpController is easy draggable even if your PullUpController's view contains a UIScrollView, just attach it to the controller itself with the following method: <#T##UIScrollView#>.attach(to: <#T##PullUpController#>)

Attach the scroll view to the provided pull up controller in order to move it with the scroll view content.

  • pullUpController: the pull up controller to move with the current scroll view content.

Demo

In this repository you can also find a demo.

Info

If you like this git you can follow me here or on twitter :) @MarioIannotta

Cheers from Italy!

Comments
  • Scrolling of inside scrollable element results in skipping

    Scrolling of inside scrollable element results in skipping

    Hi,

    I've just tried the example from the project, added just a few more elements to tableview that is inside and got this behaviour that I've recorded in video https://youtu.be/q4cU4kW-rcQ It happens when panel is fully open, inside tableview is scrolled a bit up and then when you pulling it down it starts skipping when it reaches the end by pulling the panel to compensate. Maybe it's not well explained in words, but you can see it in video :)

    Regards,

    Aleksandar

    enhancement 
    opened by vualeks 12
  • Use function instead of closures where possible

    Use function instead of closures where possible

    Haven't you thought about changing some closures to functions opened to overriding, so that you could make a few overrides? For example, I have a subclass of PullUpController ABC, which is superclass to another class CDF. To call some function from ABC on each call in CDF I have to do something like this for now. image Maybe I just don't know something.

    opened by heltisace 8
  • Jagged, not smooth animation

    Jagged, not smooth animation

    The pullup animation seems like its going to pause at an invisible sticky point in the middle of the screen( Even though the sticky point array has only 2 points - Offset and PreferredHeight) This makes the animation look incomplete and smooth Any idea on how I can resolve this?

    opened by ghost 8
  • Rotating to landscape wrongly places the controller

    Rotating to landscape wrongly places the controller

    Hey, thanks for the great library!

    We're considering using it in an existing project. I seem to have managed to customize it fine so far (with rounded corners and shadow). But I cannot seem to set up the landscapeFrame. See this video: https://www.dropbox.com/s/8pxh1rdm56fs1fm/pulluppcontroller.mp4?dl=0 When the phone rotates, the controller is placed somewhere below the screen. When it is fully expanded, it does show up a bit, but its bottom is probably somewhere below the screen bounds. Also, it is aligned next to the left screen edge, even if it should have some trailing space.

    I did override

    override var pullUpControllerPreferredLandscapeFrame: CGRect

    in my own ViewController inheriting from PullUpController. I gave it the value CGRect(x: 10, y: 20, width: 280, height: 100). Is there something else I am missing? Or maybe it is clashing with some existing code?

    opened by alexandrutomescu 6
  • Few things to add, if possible

    Few things to add, if possible

    Hi. Love you lib, though there are two things I'm concerned about:

    1. Could you add some way to change animations, except for copying the file and changing them yourself? Overriding is not quite an option because not all the functions using animation are open.
    2. On bounce or spring animation, I'm using now, there is some free space in the bottom when animating. It looks a bit weird. For now, I'm fixing it adding some extra height in pullUpControllerPreferredSize, though it would be also nice if you could do something with it, or at least I will be grateful if you could give me some advice how to do it better.

    Thanks :)

    Edit: also seems logical to call willMoveToStickyPoint and didMoveToStickyPoint on moveToVisiblePointHandling.

    enhancement 
    opened by heltisace 6
  • Bouncing `PullUp` when is going to hide

    Bouncing `PullUp` when is going to hide

    Should PullUp bounce when pullUpControllerMoveToVisiblePoint is called to 0.0 or is removed with animation? Looks a bit weird. Should that be handled by the library or better to use overriding of the bounce offset and exposed current point?

    UPD: This is not bounce issue.

    opened by heltisace 5
  • Сan't hide/show controller outside.

    Сan't hide/show controller outside.

    As I understood documentation and code, you can only change pullupVC inside itself. However, there is a needs to hide/show it outside. I think there should be delegate for that, like in default UIKit elements.

    opened by Maxatma 4
  • how to show  Fully popup Expand window ?

    how to show Fully popup Expand window ?

    i have one doubt in this pod, for eg if i click But ticket button how to show popup window ?

    Could you give the code for this ?

    For hide i use pullUpControllerMoveToVisiblePoint(pullUpControllerAllStickyPoints[0], animated: true, completion: nil) this is working

    but how to show window on event ?

    question 
    opened by isaacraja15 4
  • How to increase the visible point height

    How to increase the visible point height

    With the latest pod update I cannot increase the visible point height. Previosuly I was able to increase with increasing previewOffsetValue. Now it has been removed.

    override var pullUpControllerPreviewOffset: CGFloat {
           return 120
           //searchBoxContainerView.frame.height
       }
    
    
    question 
    opened by Confidexuta 3
  • Does not work on iPhone XR, XS, XS Max simulator

    Does not work on iPhone XR, XS, XS Max simulator

    When running on the iPhone XR Simulator, the view controller does not "drag" up slowly when using finger like it does on iPhone 7 Simulator.

    Do not have iPhone XR/XS to determine if this is a simulator issue, or issue with code.

    opened by vjdaemp 3
  • In portrait app landscape required

    In portrait app landscape required

    I'm developing an application in which only portrait orientation is available. When I started using the library I found the problem. It seemed to me that I should not override the variable pullUpControllerPreferredLandscapeFrame. But when I override only pullUpControllerPreferredSize and run my application I saw that the frame of the PullUpController was inherited from super definition of pullUpControllerPreferredLandscapeFrame. Something going wrong inside of controller. That was really confused for me. I hope this feedback will help you make your library better.

    opened by fixique 3
  • half open scrolling issue

    half open scrolling issue

    when search view controller is half opened the scorlling is not working. I have also used func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true }

    but not works. Please help

    opened by kamal3634 0
  • PullUpController crash on iPhone6 iOS 10.3.1

    PullUpController crash on iPhone6 iOS 10.3.1

    open func addPullUpController(_ pullUpController: PullUpController, initialStickyPointOffset: CGFloat, animated: Bool, completion: ((Bool) -> Void)? = nil) { assert(!(self is UITableViewController), "It's not possible to attach a PullUpController to a UITableViewController. Check this issue for more information: https://github.com/MarioIannotta/PullUpController/issues/14") addChild(pullUpController) pullUpController.setup(superview: view, initialStickyPointOffset: initialStickyPointOffset) if animated { pullUpController.pullUpControllerAnimate( action: .add, withDuration: 0.3, animations: { [weak self] in self?.view.layoutIfNeeded() // Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) }, completion: { didComplete in pullUpController.didMove(toParent: self) completion?(didComplete) } ) } else {... please help)

    opened by Al-works 0
  • UITableViewAlertForLayoutOutsideViewHierarchy

    UITableViewAlertForLayoutOutsideViewHierarchy

    I got this message. It is possible that the app will crash. With this solution * DispatchQueue.main.async {} (in line 489 of the PullUpController.swift), the message will disappear.

    Kind Regards, Ton Driessen

    DispatchQueue.main.async { if animated { pullUpController.pullUpControllerAnimate( action: .add, withDuration: 0.3, animations: { [weak self] in self?.view.layoutIfNeeded() }, completion: { didComplete in pullUpController.didMove(toParent: self) completion?(didComplete) } ) } else { self.view.layoutIfNeeded() pullUpController.didMove(toParent: self) completion?(true) } } }

    opened by 2B-Divergent 0
  • How to support ipad?

    How to support ipad?

    In Map.app on iPad, the PullUpController is located in the left top Instead bottom and its width does not equal the width of the screen. There are some differences between iPad and iPhone. In iOS 13 or newer, Apple add SceneDelegate and the size of the scene will be changed by users. So, updating the frame when it changes is also important.

    opened by jctaoo 0
  • Cannot embed pullupcontroller within tab bar view

    Cannot embed pullupcontroller within tab bar view

    Contacted you on twitter have a replicated example on me, when a tab bar view is embed into the main view the pullupcontroller is hidden under the tab bar on the iPhone X, Xr, Xs and Xs Max

    opened by hxsseeb 8
Releases(0.8.0)
  • 0.8.0(Mar 4, 2020)

  • 0.7.0(Apr 3, 2019)

  • 0.6.0(Nov 20, 2018)

  • 0.5.1(Oct 28, 2018)

    Fix releated to #33:

    • Provide a way to customize animations by overriding the method pullUpControllerAnimate(withDuration duration: TimeInterval, animations: @escaping () -> Void, completion: ((Bool) -> Void)?)
    • Fix blank space at bottom when bouncing is enabled
    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Sep 28, 2018)

    • Xcode 10 and swift 4.2 support
    • Fix issues https://github.com/MarioIannotta/PullUpController/issues/21 and https://github.com/MarioIannotta/PullUpController/issues/22

    Note: In order to show the expanded controller as initial state, and to simplify the APIs, the property pullUpControllerPreviewOffset has been removed and the method addPullUpController has been updated with a new additional parameter initialStickyPointOffset.

    Source code(tar.gz)
    Source code(zip)
  • 0.4.1(Aug 16, 2018)

  • 0.4.0(Aug 14, 2018)

    • Add updatePreferredFrameIfNeeded(animated: Bool) This method update the pull up controller's view size according to pullUpControllerPreferredSize and pullUpControllerPreferredLandscapeFrame. If the device is in portrait, the pull up controller's view will be attached to the nearest sticky point after the resize.
    • Fix #17: Scrolling of inside scrollable element results in skipping
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Jul 9, 2018)

    1. Improve animation APIs

      • Add animated property to pullUpControllerMoveToVisiblePoint
      • Add animated property to UIViewController.addPullUpController
      • Add a method to remove the pull up controller (this also fix the issue #15) UIViewController.removePullUpController(_, animated:)
    2. Add onDrag closure

    3. Add an assert to check if the user it's trying to attach a PullUpController to an UITableViewController because that's not possible, check https://github.com/MarioIannotta/PullUpController/issues/14 for more information.

    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Jun 21, 2018)

  • 0.1.0(Nov 6, 2017)

Owner
Mario Iannotta
Head of SDK and Authenticator at @KeylessTech
Mario Iannotta
A SwiftUI bottom-up controller, like in the Maps app. Drag to expand or minimize.

SwiftUI Drawer A SwiftUI bottom-up controller, like in the Maps app. Drag to expand or minimize. Contents Add the Package Basic Usage Examples Credits

Michael Verges 695 Jan 3, 2023
A controller that uses a UIStackView and view controller composition to display content in a list

StackViewController Overview StackViewController is a Swift framework that simplifies the process of building forms and other static content using UIS

Seed 867 Dec 27, 2022
A custom UIControl which functions like UISlider where you can set multiple intervals with different step values for each interval.

MultiStepSlider A custom UIControl which functions like UISlider where you can set multiple intervals with different step values for each interval. Th

Susmita Horrow 25 Apr 28, 2022
A library to imitate the iOS 10 Maps UI.

Pulley 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

52inc 2k Dec 29, 2022
UI Component. This is a copy swipe-panel from app: Apple Maps, Stocks. Swift version

ContainerController UI Component. This is a copy swipe-panel from app: https://www.apple.com/ios/maps/ Preview Requirements Installation CocoaPods Swi

Rustam 419 Dec 12, 2022
DrawerKit lets an UIViewController modally present another UIViewController in a manner similar to the way Apple's Maps app works.

DrawerKit What is DrawerKit? DrawerKit is a custom view controller presentation mimicking the kind of behaviour in the Apple Maps app. It lets any vie

Babylon Health 773 Dec 27, 2022
Play BreakOut while loading - A playable pull to refresh view using SpriteKit

BreakOutToRefresh Play BreakOut while loading - A playable pull to refresh view using SpriteKit BreakOutToRefresh uses SpriteKit to add a playable min

Dominik Hauser 2.5k Jan 5, 2023
List tree data souce to display hierachical data structures in lists-like way. It's UI agnostic, just like view-model and doesn't depend on UI framework

SwiftListTreeDataSource List tree data souce to display hierachical data structures in lists-like way. It's UI agnostic, just like view-model, so can

Dzmitry Antonenka 26 Nov 26, 2022
SheetPresentation for SwiftUI. Multiple devices support: iOS, watchOS, tvOS, macOS, macCatalyst.

SheetPresentation for SwiftUI. Multiple devices support: iOS, watchOS, tvOS, macOS, macCatalyst.

Aben 13 Nov 17, 2021
A minimalistic looking banner library for iOS. It supports multiple customizable kinds of Banner types

A minimalistic looking banner library for iOS. It supports multiple customizable kinds of Banner types

Emre Armagan 12 Oct 10, 2022
UISegmentedControl remake that supports selecting multiple segments, vertical stacking, combining text and images.

MultiSelectSegmentedControl UISegmentedControl remake that supports selecting multiple segments, vertical stacking, combining text and images. Feature

Yonat Sharon 286 Dec 15, 2022
UISlider clone with multiple thumbs and values, range highlight, optional snap intervals, optional value labels, either vertical or horizontal.

MultiSlider UISlider clone with multiple thumbs and values, range highlight, optional snap intervals, optional value labels, either vertical or horizo

Yonat Sharon 326 Dec 29, 2022
A SwiftUI Views for wrapping HStack elements into multiple lines

SwiftUI WrappingStack A SwiftUI Views for wrapping HStack elements into multiple lines. List of supported views WrappingHStack - provides HStack that

Denis 50 Jan 6, 2023
iOS custom controller used in Jobandtalent app to present new view controllers as cards

CardStackController iOS custom controller used in the Jobandtalent app to present new view controllers as cards. This controller behaves very similar

jobandtalent 527 Dec 15, 2022
Provides an iOS view controller allowing a user to draw their signature with their finger in a realistic style.

Swift version now available! Mimicking pen-on-paper signatures with a touch screen presents a difficult set of challenges. The rate touch events are e

Uber Open Source 1.3k Jan 6, 2023
Meet Page View Controller for iOS by Cleveroad

While a standard page view allows you to navigate between pages by using simple gestures, our component goes further

Cleveroad 397 Aug 20, 2022
AGCircularPicker is helpful component for creating a controller aimed to manage any calculated parameter

We are pleased to offer you our new free lightweight plugin named AGCircularPicker. AGCircularPicker is helpful for creating a controller aimed to man

Agilie Team 617 Dec 19, 2022
A child view controller framework that makes setting up your parent controllers as easy as pie.

Description Family is a child view controller framework that makes setting up your parent controllers as easy as pie. With a simple yet powerful publi

Christoffer Winterkvist 246 Dec 28, 2022
A library, which adds the ability to hide navigation bar when view controller is pushed via hidesNavigationBarWhenPushed flag

HidesNavigationBarWhenPushed A library, which adds the ability to hide navigation bar when view controller is pushed via hidesNavigationBarWhenPushed

Danil Gontovnik 55 Oct 19, 2022