Tweet-sheet style modal in iOS (in Swift)

By: Megha Bambra

This post is continuation of the last blog post (click here) and demonstrates how Tweet-sheet style modals can be achieved. To quickly review, 

  • Setup a storyboard with a view controller
  • Place a container inside that view controller
  • Place another a Navigational Controller, Table View Controller and another View Controller inside the storyboard
  • Embed the Navigational Controller inside the container

This is how the setup would look like on a storyboard:

 

This basically forms the foundation of views that will make our Tweet-sheet style modal - something like below (end result): 

TableView.gif

Ok let's start with step 1 - which is the 'holder' view controller. Below, the image highlights how the view controller is setup. Following are the main components in the view:

  • At the base, there is a background image
  • UIButton that will be used to present the modal
  • UIButton that will be used to dismiss the modal - this button spans the width and height of the VC and has a bit of opacity that gives modal a better presentation effect
  • A container view which embeds the navigational controller

As a side note, ensure you have a ModalViewController.swift created (or whatever you want to name the ViewController) and applied a custom class in the storyboard.

Now it's time to get into some Swift code :)  Let's start with creating @IBOutlets for:

  • UIButton which will dismiss the modal
  • UIView which is the container

And create @IBAction for:

  • Showing the modal
  • Dismissing the modal

Now hook these up to the appropriate objects in the storyboard as you would do normally.

    
    @IBOutlet var containerView: UIView
    
    @IBOutlet var btnDismiss: UIButton
    
    @IBAction func dismissModal(AnyObject) {}
    
    @IBAction func showModal(AnyObject) {}

Next, let's setup so that we can show and dismiss the modal with nice fade transition in and out:

    func modalManagement(shouldBeHidden:Bool) {
        if shouldBeHidden {
            fadeOutAnimationWithView(self.containerView)
            self.btnDismiss.hidden = true
        } else {
            fadeInAnimationWithView(self.containerView)
            self.btnDismiss.hidden = false
        }
    }
    
    func fadeInAnimationWithView(view:UIView) {
        view.alpha = 0.0;
        UIView .beginAnimations(nil, context: nil)
        UIView .setAnimationDuration(0.4)
        UIView .setAnimationDelegate(self)
        view.alpha = 1.0;
        UIView .commitAnimations()
        view.hidden = false
    }

    func fadeOutAnimationWithView(view:UIView) {
        UIView .beginAnimations(nil, context: nil)
        UIView .setAnimationDuration(0.4)
        UIView .setAnimationDelegate(self)
        view.alpha = 0.0;
        UIView .commitAnimations()
        view.hidden = true
    }

And now to let the magic happen, let's call these in our show/dismiss @IBOutlets:

    @IBAction func dismissModal(AnyObject) {
        modalManagement(true)
    }
    
    @IBAction func showModal(AnyObject) {
        modalManagement(false)
    }

This is it! I would love to hear your feedback on the post and how you utilized this approach in doing modals. Stay tuned for more posts on iOS and Swift.