Modal controller as in mail or Apple music application. Similar animation and transition. I tried to repeat all the animations, corner radius and frames. The controller supports gestures and Navigation Bar & work with ScrollView. You can see how use pod tutorial on youtube

Preview GIF loading 3mb. Please, wait


You can download example in AppStore. If you want buy code of app on gif, please, contact me. Price: $200. Source code can be used for educational purposes only


Swift 4.2. Ready for use on iOS 10+


Drop in Source/SPStorkController folder to your Xcode project. Make sure to enable Copy items if needed and Create groups.

Or via CocoaPods:

pod 'SPStorkController'

How to use

Create controller and set transitioningDelegate to SPStorkTransitioningDelegate object. Use present or dismiss functions:

import UIKit
import SPStorkController

class ViewController: UIViewController {
    override func viewDidAppear(_ animated: Bool) {

        let controller = UIViewController()
        let transitionDelegate = SPStorkTransitioningDelegate()
        controller.transitioningDelegate = transitionDelegate
        controller.modalPresentationStyle = .custom
        self.present(controller, animated: true, completion: nil)

Please, not init SPStorkTransitioningDelegate like here:

controller.transitioningDelegate = SPStorkTransitioningDelegate()

You will get error about weak property.

Light StatusBar

For set light status bar for presented controller, user preferredStatusBarStyle propert. Also set modalPresentationCapturesStatusBarAppearance. See example:

import UIKit

class ModalViewController: UIViewController {
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    override func viewDidLoad() {
        self.modalPresentationCapturesStatusBarAppearance = true


  • Parameter isSwipeToDismissEnabled enables dissmiss by swipe gester. Defualt is true:
transitionDelegate.isSwipeToDismissEnabled = true
  • Parameter isTapAroundToDismissEnabled enables dissmiss by tap parrent controller. Defualt is true:
transitionDelegate.isTapAroundToDismissEnabled = true
  • Parameter showIndicator shows or hides top arrow indicator. Defualt is true:
transitionDelegate.showIndicator = true
  • Parameter customHeight sets custom height for modal controller. Defualt is nil:
transitionDelegate.customHeight = 350

Add Navigation Bar

You may want to add a navigation bar to your modal controller. Since it became impossible to change or customize the native controller in swift 4 (I couldn’t even find a way to change the height of bar), I had to completely create navigation bar. Visually, it looks real, but it doesn’t execute the necessary functions:

import UIKit

class ModalController: UIViewController {
    let navBar = SPFakeBarView(style: .stork)
    override func viewDidLoad() {

        self.view.backgroundColor = UIColor.white

        self.navBar.titleLabel.text = "Title"
        self.navBar.leftButton.setTitle("Cancel", for: .normal)
        self.navBar.leftButton.addTarget(self, action: #selector(self.dismissAction), for: .touchUpInside)


You only need to add a navigation bar to the main view, it will automatically layout. Use style .stork in init SPFakeBarView. It is image preview with Navigation Bar and without it:


For use SPFakeBarView you should install SparrowKit pod:

pod 'SparrowKit'

Work with UIScrollView

If you use UIScrollView (or UITableView & UICollectionView) on your controller, I recommend making it more interactive. When the scroll reaches the top position, the controller will interactively drag down, simulating a closing animation. To do this, set the delegate and in the function scrollViewDidScroll call:

func scrollViewDidScroll(_ scrollView: UIScrollView) {

Work with UITableView & UICollectionView

Working with a collections classes is not difficult. In the Example folder you can find the implementation, however I will give a couple of tips to help the table look better.

For fist, if you use SPFakeBarView, don't forget set top insets for content & scroll indicator. Also I am recomeded set bottom insets:

tableView.contentInset.top = self.navBar.height
tableView.scrollIndicatorInsets.top = self.navBar.height

tableView.contentInset.bottom = self.safeAreaInsets.bottom
tableView.scrollIndicatorInsets.bottom = self.safeAreaInsets.bottom

Please, use also SPStorkController.scrollViewDidScroll() function in delegate for more interactive with your collection or table view

Modal presentation other controller

If you want present modal controller on SPStorkController, please, set:

controller.modalPresentationStyle = .custom

It need for correct presentation and dimissing all modal controllers.

My projects

Here I would like to offer you my other projects.


Project SPPermission for managing permissions with the customizable visual effects. Beautiful dialog increases the chance of approval (which is important when we request notification). Simple control of this module saves you hours of development. You can start using project with just two lines of code and easy customization!



The SPStorkController in the past was part of SparrowKit library. In library you can find many useful extensions & classes. For install via CocoaPods use:

pod 'SparrowKit'