Last active
October 19, 2023 11:04
-
-
Save DavidNix/d297696152315c1157b9ed553efa472f to your computer and use it in GitHub Desktop.
iOS example of using UIViewControllerTransitioningDelegate to create a slide to reveal effect.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A common effect when you press a hamburger button. | |
public class SlideRevealTransitioner: NSObject { | |
private let percentage: CGFloat | |
public init(percentage: CGFloat) { | |
self.percentage = percentage | |
} | |
private var presenting = true | |
} | |
extension SlideRevealTransitioner: UIViewControllerTransitioningDelegate { | |
public func animationControllerForPresentedController(presented: UIViewController, | |
presentingController presenting: UIViewController, | |
sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { | |
self.presenting = true | |
return self | |
} | |
public func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { | |
self.presenting = false | |
return self | |
} | |
} | |
extension SlideRevealTransitioner: UIViewControllerAnimatedTransitioning { | |
public func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval { | |
return 0.3 | |
} | |
public func animateTransition(transitionContext: UIViewControllerContextTransitioning) { | |
guard let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey), | |
let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) else { | |
return | |
} | |
if presenting { | |
show(toVC, fromVC: fromVC, context: transitionContext) | |
} else { | |
hide(toVC, fromVC: fromVC, context: transitionContext) | |
} | |
} | |
} | |
private extension SlideRevealTransitioner { | |
func show(toVC: UIViewController, fromVC: UIViewController, context: UIViewControllerContextTransitioning) { | |
guard let containerView = context.containerView() else { | |
return | |
} | |
let finalFrame = CGRectOffset(fromVC.view.frame, fromVC.view.bounds.width * percentage, 0) | |
toVC.view.frame = fromVC.view.frame | |
containerView.addSubview(toVC.view) | |
let originalSuperview = fromVC.view.superview | |
containerView.addSubview(fromVC.view) | |
toVC.beginAppearanceTransition(true, animated: true) | |
UIView.animateWithDuration(transitionDuration(context), animations: { | |
fromVC.view.frame = finalFrame | |
}) { finished in | |
context.completeTransition(true) | |
originalSuperview?.addSubview(fromVC.view) | |
containerView.superview?.bringSubviewToFront(containerView) | |
toVC.endAppearanceTransition() | |
} | |
} | |
func hide(toVC: UIViewController, fromVC: UIViewController, context: UIViewControllerContextTransitioning) { | |
let containerView = context.containerView() | |
let finalFrame = context.finalFrameForViewController(toVC) | |
let originalSuperview = toVC.view.superview | |
containerView?.addSubview(toVC.view) | |
toVC.beginAppearanceTransition(true, animated: true) | |
UIView.animateWithDuration(transitionDuration(context), animations: { | |
toVC.view.frame = finalFrame | |
}) { finished in | |
originalSuperview?.addSubview(toVC.view) | |
fromVC.view.removeFromSuperview() | |
context.completeTransition(true) | |
toVC.endAppearanceTransition() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment