Lazy pop and dismiss like in the Facebook, Instagram or Twitter apps.
Swift Objective-C Ruby
Switch branches/tags
Latest commit a18ecd1 May 23, 2017 @serp1412 serp1412 Update README.md

README.md

LazyTransitions

Platform: iOS 8+ Language: Swift 3 Cocoapods Carthage Compatible License: BSD Twitter: serp1412

A simple framework that allows you to create similar lazy pops and dismisses like in the Facebook, Instagram or Twitter apps.

LazyTransitions

Installation

CocoaPods

Add the following line to your PodFile:

pod 'LazyTransitions'

Carthage

Add the following line to your Cartfile

github "serp1412/LazyTransitions"

Usage

The simplest way to use this framework is to take advantage of LazyTransitioner class.

  • Import the framework
import LazyTransitions
  • Create an instance of LazyTransitioner
let transitioner = LazyTransitioner()
  • Pass your transition views (views that will trigger a transition when user pans on them) to the transitioner
transitioner.addTransition(forView: view)
// or
transitioner.addTransition(forScrollView: scrollView)
  • In the triggerTransitionAction trigger your transition (dismiss or pop)
transitioner.triggerTransitionAction = { [weak self] _ in
    self?.dismiss(animated: true, completion: nil)
}
  • Set your transitioner as the transitioning delegate of the view controller you're dismissing.

For Dismiss:

transitioningDelegate = transitioner

NOTE: if your view controller is embedded in another view controller you'll have to assign to your parent's transitioning delegate. In case of a screen embedded in a UINavigationController you have to do:

navigationController?.transitioningDelegate = transitioner

For Pop:

navigationController?.delegate = transitioner

Example

Here's some sample code on how to use LazyTransitions in your project.

// first of all import LazyTransitions
import LazyTransitions

class MyVC : UIViewController {
    fileprivate let transitioner = LazyTransitioner()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // add the main view to your transitioner
        transitioner.addTransition(forView: view)
        
        // trigger the transition in triggerTransitionAction
        transitioner.triggerTransitionAction = { [weak self] _ in
            // for dismiss
            self?.dismiss(animated: true, completion: nil)
            // or for pop
            _ = self?.navigationController?.popViewController(animated: true)
        }
        
        // FOR DISMISS
        // set transitioner as the delegate for custom view controller transitioning
        transitioningDelegate = transitioner
        
        // or FOR POP
        // set transitioner as the delegate for your navigation controller
        navigationController.delegate = transitioner
    }
}

Usage Tips

  • To add the a bouncy effect when user scrolls with inertia and the UIScrollView reaches its edges, do the following:
// become the delegate of your UIScrollView
scrollView.delegate = self

// implement the scrollViewDidScroll() delegate method
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    // forward it to the transitioner
    transitioner.didScroll(scrollView)
}
  • To achieve the standard pop animation of iOS, use the provided PopAnimator when initializing the LazyTransitioner
let transitioner = LazyTransitioner(animator: PopAnimator(orientation: .leftToRight))
  • You can limit the allowed transition orientations by setting them like this:
transitioner.allowedOrientations = [.leftToRight, .topToBottom, .bottomToTop]
  • In case you need to assign something else as the transitioning delegate, then you can simply forward the animator and interactor properties of your transitioner inside the delegate methods.

Like so in case of dismiss:

func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    // ... pass the animator
    return transitioner.animator
}
    
func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
    // ... pass the interactor
    return transitioner.interactor
}