You can dismiss modal viewcontroller like Facebook Messenger by pulling scrollview or navigationbar in Swift.

Overview

PullToDismiss

PullToDismiss provides dismiss modal viewcontroller function like Facebook Messenger by pulling scrollview or navigationbar with smooth and rich background effect.

GitHub release Language Carthage Compatible CocoaPods CocoaPodsDL Awesome Reviewed by Hound


sample blur sample
gif gif

Feature

  • Support all scroll views. (UIScrollView, UITableView, UICollectionView, UIWebView, WKWebView)
  • Customizable. (dismiss background color, alpha, height percentage of dismiss)
  • Available in UIViewController, UINavigationController.
  • Automatically add pan gesture to navigation bar.
  • Blur effect support.
  • Objective-C support. (from v2.1~)

Migration guide

If you update from 1.x to 2.0, see migration guide if needed.

Usage

Getting Started

(1) Setup PullToDismiss

import PullToDismiss

class SampleViewController: UIViewController {
    @IBOutlet private weak var tableView: UITableView!
    private var pullToDismiss: PullToDismiss?
    override func viewDidLoad() {
        super.viewDidLoad()
        pullToDismiss = PullToDismiss(scrollView: tableView)
    }
}

(2) Create view controller and set modalPresentationStyle. Then present view controller

let vc = SampleViewController()
let nav = UINavigationController(rootViewController: vc)
nav.modalPresentationStyle = .overCurrentContext

self.present(nav, animated: true, completion: nil)

๐Ÿ‘ ๐Ÿ‘ ๐Ÿ‘

Use (UIScrollView|UITableView|UICollectionView)Delegate

You can use all scroll view's delegate by set pullToDismiss.delegate.

import PullToDismiss

class SampleViewController: UIViewController {
    @IBOutlet private weak var tableView: UITableView!
    private var pullToDismiss: PullToDismiss?
    override func viewDidLoad() {
        super.viewDidLoad()
        pullToDismiss = PullToDismiss(scrollView: tableView)
        pullToDismiss?.delegate = self
    }
}

extension SampleViewController: UITableViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        // ...
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // ...
    }
}

Customize

You can customize backgroundEffect, dismissableHeightPercentage:

Shadow background effet

  • background (default: ShadowEffect.default, [color: black, alpha: 0.8])

img1

pullToDismiss?.background = ShadowEffect(color: .red, alpha: 0.5) // color: red, alpha: 0.5

Blur background effect

New feature for v1.0.

gif

// preset blur (.extraLight, .light, .dark)
pullToDismiss?.background = BlurEffect.extraLight

// set custom Blur
pullToDismiss?.background = BlurEffect(color: .red, alpha: 0.5, blurRadius: 40.0, saturationDeltaFactor: 1.8)

dismissableHeightPercentage

img2

// to pull half size of view controller, dismiss view controller.
pullToDismiss?.dismissableHeightPercentage = 0.5

Requirements

  • iOS 8.0+ (blur effect: iOS 9.0+)
  • Xcode 8.1+
  • Swift 3.0+

Installation

Carthage

  • Add the following to your Cartfile:
# Swift 5.0 or later
github "sgr-ksmt/PullToDismiss" ~> 2.2
# Swift 3
github "sgr-ksmt/PullToDismiss", 2.1
  • Run carthage update
  • Add the framework as described.
    Details: Carthage Readme

CocoaPods

PullToDismiss is available through CocoaPods. To install it, simply add the following line to your Podfile:

# Swift 5.0 or later
pod 'PullToDismiss', '~> 2.2'
# Swift 3
pod 'PullToDismiss', '2.1'

and run pod install

Manually Install

Download all *.swift files and put your project.

Change log

Change log is here.

Communication

  • If you found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request. ๐Ÿ’ช

License

PullToDismiss is under MIT license. See the LICENSE file for more info.

Comments
  • Updates README with updated backgroundEffect

    Updates README with updated backgroundEffect

    Previous README was a bit outdated and the instructions for backgroundEffect said pullToDismiss?.background instead of pullToDismiss?.backgroundEffect, which confused me so I took a look at the source code and corrected the mistake in case anybody else uses this and is confused


    Updates the README to what current source code for PullToDismiss.swift looks like

    opened by mding5692 2
  • need to update syntax in Swift 5

    need to update syntax in Swift 5

    • UIBlurEffectStyle has been renamed to UIBlurEffect.Style -> this is the error in CustomBlurView: UIVisualEffectView
    • .sendSubview(toBack:) has been renamed to sendSubviewToBack(_:) -> this is the error in class PullToDismiss: NSObject
    opened by j-elmer123 1
  • Adding actions for beginning and ending dismiss.

    Adding actions for beginning and ending dismiss.

    This is in order to prepare the underlying view for any updates that occurred on the view above.

    Because the dismiss percentage is abstracted and private, this or something similar is necessary in some applications/instances.

    opened by benguild 1
  • Fixing issue with `UIPageViewController` outermost parent.

    Fixing issue with `UIPageViewController` outermost parent.

    I noticed that this works well with UIPageViewController (embedded within an additional parent, for example) only if resolving the topmost parent UIViewController. I'm assuming that this is probably most ideal in all situations, but that the previous convenience of calling "dismiss" on the closest UIViewController also worked in most instances.

    This fixes the issue that I ran into. โ€” An alternative would be to have a weak property that can be overridden to track which UIViewController to actually dismiss in case it's a less typical choice, but I'm guessing that's unnecessary.

    opened by benguild 1
  • Updates backgroundEffect code on README

    Updates backgroundEffect code on README

    @sgr-ksmt Previously README had pullToDismiss?.background instead of pullToDismiss?.backgroundEffect which was wrong and confused me and I figured it out by looking through the source code for PullToDismiss.swift. Thanks again for this repo! ๐Ÿ‘

    Issue

    • Issue Number: #39

    Updates the README.md so that it has the correct instructions for changing PullToDismiss's backgroundEffect.

    opened by mding5692 1
  • README is outdated

    README is outdated

    Thanks again for the repo and open sourcing it, using it currently right now in my app and I noticed an issue with the README. Probably going to post a PR soon as its an easy change.

    The README says pullToDismiss?.background instead of pullToDismiss?.backgroundEffect for changing the background which is wrong and I figured it out through having to look through the source code PullToDismiss.swift.

    opened by mding5692 1
  • Added support for Objective-C

    Added support for Objective-C

    Added Objective-C compatibility. Tested in a live production app and it works without any issues. Structs are now classes inheriting from NSObject, and extensions are public. I don't believe this will cause any issues with existing swift integrations, but I'd be happy to look into this further if that is in fact the case.

    opened by MrMatthewDavis 1
  • Release/2.0

    Release/2.0

    • [x] Realistic animation #24, #26
    • [x] Redesign of ProxyDelegate #25, #27
    • [x] Update README.md
    • [x] Prepare Migration Guide
    • [x] Create unavailable.swift for migration from 1.x.
    • [x] Update CHANGELOG.md
    opened by sgr-ksmt 1
  • Redesign of proxyDelegate

    Redesign of proxyDelegate

    As of now, we need some specific delegate methods to make PullToDismiss work. If we want to use delegate methods other than the specific ones, we have no choice but to implement them as a method in PullToDismiss's subclass.

    You know, that is not cool. ๐Ÿ˜ข

    class CustomPullToDismiss: PullToDismiss {
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return tableViewDelegate?.tableView?(tableView, heightForRowAt: indexPath) ?? 44.0
        }
    }
    
    class SampleViewController: UIViewController {
        @IBOutlet private weak var tableView: UITableView!
        private var pullToDismiss: PullToDismiss?
        override func viewDidLoad() {
            super.viewDidLoad()
            pullToDismiss = CustomPullToDismiss(scrollView: tableView)
            pullToDismiss.delegateProxy = self
        }
    }
    
    extension SampleViewController: UITableViewDelegate {
        // called by CustomPullToDismiss
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return indexPath.section == 0 ? 44.0 : 60.0
        }
    
        // ...
    }
    

    That is why I decided to restructure the design of delegate proxy so that implementing more delegate methods into the subclass will be no longer needed.

    opened by sgr-ksmt 0
  • Is there a way to present so it doesn't take up the entire superview?

    Is there a way to present so it doesn't take up the entire superview?

    Is there a way to specify the hieght of the PullToDismiss view, without having it take up the entire screen? I tried this:

    let vc = LikesTableController()
            vc.preferredContentSize = CGSize(width: view.frame.width, height: 200)
            present(vc, animated: true)
    

    but it doesn't work....

    opened by jderbs 0
  • TableView Delegate not work

    TableView Delegate not work

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    }

    this function of UITableView does not work when using PullToDismiss. How to fix it ?????

    opened by ghost 1
  • [bug] Status-bar-hiding avoiding code doesn't work consistently

    [bug] Status-bar-hiding avoiding code doesn't work consistently

    This doesn't always work: https://github.com/sgr-ksmt/PullToDismiss/blob/master/Sources/PullToDismiss.swift#L173-L175

    Example: if you drag a UINavigationController with a UIViewController that has a UIScrollView in it, upward (into negative space) before dragging it downward, it may skip over the detection range of 0 -> 0.5 that's prescribed here, and the status bar is hidden on that view.

    Depending on what you're doing, this is an oversight.

    opened by benguild 1
  • New feature request: Dismissing is too sensitive to drag velocity

    New feature request: Dismissing is too sensitive to drag velocity

    Hi, I find the dismiss action too sensitive to drag velocity, so that the modal is dismissed too easily. Is it possible to expose some property (similar to dismissableHeightPercentage property) so that we're able to increase resistance to drag velocity?

    opened by ElectroBuddha 1
Releases(2.1)
Owner
Suguru Kishimoto
iOS/Web Developer and Technical Advisor for Firebase. ๐Ÿ’–:Swift/TypeScript/Firebase/React
Suguru Kishimoto
Fully customizable Facebook reactions like control

Reactions is a fully customizable control to give people more ways to share their reaction in a quick and easy way. Requirements โ€ข Usage โ€ข Installatio

Yannick Loriot 585 Dec 28, 2022
A draggable modal for iOS Applications.

Mantle Modal Draggable Modal, PopUp or Menu written in Swift. Description A simple modal resource that uses a UIScrollView to allow the user to close

Ricardo Canales 89 Feb 25, 2022
ScrollView that supports a parallax header image and static overlay.

ScrollViewReactiveHeader A replacement ScrollView that provides a header with subtle scroll animations. example-video.mov Using ScrollViewReactiveHead

null 49 Dec 29, 2022
A SwiftUI ScrollView that only scrolls if the content doesn't fit in the View

ScrollViewIfNeeded A SwiftUI ScrollView that only scrolls if the content doesn't fit in the View Installation Requirements iOS 13+ Swift Package Manag

Daniel Klรถck 19 Dec 28, 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
Protocol to handle initial Loadings, Empty Views and Error Handling in a ViewController & views

StatusProvider Protocol to handle initial Loadings, Empty Views and Error Handling in a ViewController & views CocoaPods Podfile pod 'StatusProvider'

Mario Hahn 887 Dec 22, 2022
Simple PhotoBrowser/Viewer inspired by facebook, twitter photo browsers written by swift

SKPhotoBrowser Simple PhotoBrowser/Viewer inspired by facebook, twitter photo browsers written by swift features Display one or more images by providi

keishi suzuki 2.4k Jan 6, 2023
FacebookMe is a Swift App Mimics the personal profile tab of Facebook.

FacebookMe FacebookMe is a Swift App Mimics the personal profile tab of Facebook. It demos one simple way to implement a UITableView with mutiple sect

Kushal Shingote 3 Feb 20, 2022
Newly is a drop in solution to add Twitter/Facebook/Linkedin style, new updates/tweets/posts available button

Newly is a drop in solution to add Twitter/Facebook/Linkedin style, new updates/tweets/posts available button. It can be used to notify user about new content availability and can other actions can be triggers using its delegate method.

Dhiraj Rajendra Jadhao 197 Sep 22, 2022
Bar Button Item that can be moved anywhere in the screen, like Android's stickers button.

FlowBarButtonItem Bar Button Item that can be moved anywhere in the screen, like Android's stickers button. [![CI Status](http://img.shields.io/travis

noppefoxwolf 153 Sep 15, 2022
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
A nice iOS View Capture Swift Library which can capture all content.

SwViewCapture A nice iOS View Capture Library which can capture all content. SwViewCapture could convert all content of UIWebView to a UIImage. ไธ€ไธช็”จ่ตทๆฅ่ฟ˜

Xing Chen 597 Nov 22, 2022
๐Ÿž Toast for Swift - Toaster Android-like toast with very simple interface

Toaster Android-like toast with very simple interface. (formerly JLToast) Screenshots Features Queueing: Centralized toast center manages the toast qu

Suyeol Jeon 1.6k Jan 3, 2023
๐Ÿ” Awesome fully customize search view like Pinterest written in Swift 5.0 + Realm support!

YNSearch + Realm Support Updates See CHANGELOG for details Intoduction ?? Awesome search view, written in Swift 5.0, appears search view like Pinteres

Kyle Yi 1.2k Dec 17, 2022
This widget displays a weight and a label. It can be used in the summary view for a strength assessment.

Strength Assessment Widget - Flutter Modern UI engineering is all about components. When we build components to be reusable, we enable faster iteratio

null 1 Feb 18, 2022
A fancy hexagonal layout for displaying data like your Apple Watch

Hexacon is a new way to display content in your app like the Apple Watch SpringBoard Highly inspired by the work of lmmenge. Special thanks to zenly f

Gautier Gรฉdoux 340 Dec 4, 2022
A horizontal scroll dial like Instagram.

HorizontalDial Preview Requirements iOS 8.0+ Swift 5 Storyboard support Installation CocoaPods use_frameworks! pod "HorizontalDial" Manually To instal

Lee Sun-Hyoup 210 Nov 22, 2022
RangeSeedSlider provides a customizable range slider like a UISlider.

RangeSeekSlider Overview RangeSeekSlider provides a customizable range slider like a UISlider. This library is based on TomThorpe/TTRangeSlider (Objec

WorldDownTown 644 Dec 12, 2022