TransitionController
You can dismiss transition and present transition between UIViewController, UINavigationController, UITabBarController, UICollectionViewController, and UITableViewController.
Receives a delegate for the willPresent, didPresent, willDismiss and didDismiss of the ViewController.
Requirements
TransitionController
written in Swift 5.0. Compatible with iOS 8.0+
Installation
TransitionController is available through CocoaPods. To install
it, simply add the following line to your Podfile:
pod 'TransitionController'
Usage
import TransitionController
class ImageViewController {
@IBOutlet private weak var imageView: UIImageView!
@IBAction private func transitionTap(_ sender: UIButton) {
guard let viewController = UIStoryboard(name: "Image", bundle: nil).instantiateViewController(withIdentifier: "ImageTransitionController") as? ImageTransitionController else { return }
// let viewController = ImageTransitionController()
viewController.transitionDelegate = self
viewController.imageView.image = self.imageView.image
self.present(viewController, animated: true, completion: nil)
}
}
// MARK: TransitionDelegate
extension ImageViewController: TransitionDelegate {
var transitionSuperview: UIView {
return self.view
}
func transitionPresentFromView(_ base: BaseTransition) -> UIView? {
return self.imageView
}
func transitionPresentFromImage(_ base: BaseTransition) -> UIImage? {
return self.imageView.image
}
func transitionDismissToView(_ base: BaseTransition) -> UIView? {
return self.imageView
}
}
TransitionController
import UIKit
import TransitionController
class ImageTransitionController: TransitionViewController {
@IBOutlet weak var imageView: UIImageView!
override var presentToView: UIView? {
let view = UIView(frame: self.imageView.frameForImageInImageViewAspectFit)
view.contentMode = .scaleAspectFit
return view
}
override var dismissFromView: UIView? {
return self.imageView
}
override var dismissFromImage: UIImage? {
return self.imageView.image
}
}
extension UIImageView {
var frameForImageInImageViewAspectFit: CGRect {
if let img = self.image {
let imageRatio = img.size.width / img.size.height
let viewRatio = self.frame.size.width / self.frame.size.height
if(imageRatio < viewRatio) {
let scale = self.frame.size.height / img.size.height
let width = scale * img.size.width
let topLeftX = (self.frame.size.width - width) * 0.5
return CGRect(x: topLeftX, y: 0, width: width, height: self.frame.size.height)
} else {
let scale = self.frame.size.width / img.size.width
let height = scale * img.size.height
let topLeftY = (self.frame.size.height - height) * 0.5
return CGRect(x: 0, y: topLeftY, width: self.frame.size.width, height: height)
}
}
return CGRect(x: 0, y: 0, width: 0, height: 0)
}
}
Done! ???
Superclass
class ExampleViewController: TransitionViewController {
}
class ExampleNavigationController: TransitionNavigationController {
}
class ExampleTabBarController: TransitionTabBarController {
}
class ExampleTableViewController: TransitionTableViewController {
}
class ExampleCollectionViewController: TransitionCollectionViewController {
}
BaseTransition Controller protocol
// indexPath or sequence or etc
var key: Any? { set get }
// transitionContext.containerView
// Top-level view of a transition
var containerView: UIView? { get }
// duration when present
var presentDuration: TimeInterval { get }
// destination view when present
var presentToView: UIView? { get }
// duration when dismiss
var dismissDuration: TimeInterval { get }
// Start point view when dismiss
var dismissFromView: UIView? { get }
// Start point image when dismiss
var dismissFromImage: UIImage? { get }
// gesture enabled
// UINavigationController Back Swipe: UIScreenEdgePanGestureRecognizer
// Transition Gesture: UIPanGestureRecognizer
func transitionRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool
Delegate
// MARK: TransitionDelegate
extension ViewController: TransitionDelegate {
var transitionSuperview: UIView {
return self.view
}
func transitionPresentFromView(_ base: BaseTransition) -> UIView? {
return self.imageView
}
func transitionPresentFromImage(_ base: BaseTransition) -> UIImage? {
return self.imageView.image
}
func transitionDismissToView(_ base: BaseTransition) -> UIView? {
return self.imageView
}
func transitionWillPresent(_ base: BaseTransition, viewController: UIViewController) {
print("transitionWillPresent")
}
func transitionDidPresent(_ base: BaseTransition, viewController: UIViewController) {
print("transitionDidPresent")
}
func transitionWillDismiss(_ base: BaseTransition, viewController: UIViewController) {
print("transitionWillDismiss")
}
func transitionDidDismiss(_ base: BaseTransition, viewController: UIViewController) {
print("transitionDidDismiss")
}
func transitionGesture(_ base: BaseTransition, viewController: UIViewController, gesture: UIPanGestureRecognizer, progress: CGFloat) {
switch gesture.state {
case .began:
base.transitionView.backgroundColor = .black
case .changed:
base.transitionView.backgroundColor = UIColor.black.withAlphaComponent(progress / 3)
default:
break
}
}
}