Proof of concept of adding swipe-dismiss logic to a view controller, supporting Auto Layout and dynamic height.



This isn’t proper open-source code, so no package managers are supported yet. Just add the files from the PanelController to your project.

To make use of the behavior that PanelController provided, make sure your view controller conforms to PanelPresentable and set its viewController property to self in your initializer. If you do this at a later stage, your view controller will not presented in a nice way.

class SimpleViewController: UIViewController, PanelPresentable {
    let panelController = PanelController()
    init() {
        super.init(nibName: nil, bundle: nil)
        panelController.viewController = self

Make sure to add your views to the contentView property, which is forwarded to the view is panelController‘s scroll view. And any navigation-type views can be placed in the topContentView which will be displayed above your content and will stick to the top of the screen when scrolling.

    private lazy var simpleView: UIView = {
        let view = UIView()
        view.backgroundColor = .systemMint
        return view
    private lazy var cancelButton: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("Cancel", for: .normal)
        button.addAction(UIAction { [unowned self] _ in
            self.presentingViewController?.dismiss(animated: true)
        }, for: .touchUpInside)
        return button
    override func viewDidLoad() {
        view.tintColor = .black
        simpleView.translatesAutoresizingMaskIntoConstraints = false
        cancelButton.translatesAutoresizingMaskIntoConstraints = false
            simpleView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            simpleView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            simpleView.topAnchor.constraint(equalTo: contentView.topAnchor),
            simpleView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            simpleView.heightAnchor.constraint(equalToConstant: 200),
            cancelButton.leadingAnchor.constraint(equalTo: topContentView.layoutMarginsGuide.leadingAnchor),
            cancelButton.centerYAnchor.constraint(equalTo: topContentView.layoutMarginsGuide.centerYAnchor)

Example code

In the repo you‘ll find SimpleViewController that does something simular as the code showed above. A more complex example is StackViewController where a bunch of random, multiline labels can be added to a UIStackView. The height animates whenever the a label is added or removed. In the animateChanges() method an example is shown how to animate the height change by wrapping self.view.layoutIfNeeded() in an animation closure.


Look me up on twitter! ✌🏻


View Github