Skip to content

Instantly share code, notes, and snippets.

@keitaoouchi
Created June 14, 2018 06:48
Show Gist options
  • Save keitaoouchi/436c097c417524d84bda921a57f4a536 to your computer and use it in GitHub Desktop.
Save keitaoouchi/436c097c417524d84bda921a57f4a536 to your computer and use it in GitHub Desktop.
Custom popup presenting transition
import Foundation
import UIKit
final class PopupTransition: NSObject, UIViewControllerAnimatedTransitioning {
enum Mode {
case present
case dismiss
}
let duration: TimeInterval
let originFrame: CGRect
let mode: Mode
init(duration: TimeInterval, originFrame: CGRect, mode: Mode) {
self.duration = duration
self.originFrame = originFrame
self.mode = mode
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return self.duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
switch mode {
case .present:
presentAnimation(using: transitionContext)
case .dismiss:
dismissAnimation(using: transitionContext)
}
}
private func presentAnimation(using transitionContext: UIViewControllerContextTransitioning) {
// Setup
let containerView = transitionContext.containerView
let toView = transitionContext.view(forKey: .to)!
let initialFrame = originFrame
let finalFrame = toView.frame
toView.transform = CGAffineTransform(
scaleX: initialFrame.width / finalFrame.width,
y: initialFrame.height / finalFrame.height
)
toView.center = CGPoint(x: initialFrame.midX, y: initialFrame.midY)
containerView.addSubview(toView)
UIView.animate(
withDuration: duration,
delay: 0.0,
usingSpringWithDamping: 0.4,
initialSpringVelocity: 0.0,
animations: {
toView.transform = .identity
toView.center = CGPoint(x: finalFrame.midX, y: finalFrame.midY)
},
completion: { _ in
transitionContext.completeTransition(true)
}
)
}
private func dismissAnimation(using transitionContext: UIViewControllerContextTransitioning) {
// Setup
let containerView = transitionContext.containerView
let fromView = transitionContext.view(forKey: .from)!
let toView = transitionContext.view(forKey: .to)!
let initialFrame = fromView.frame
let finalFrame = originFrame
containerView.addSubview(toView)
containerView.bringSubview(toFront: fromView)
// Animation
UIView.animate(
withDuration: duration,
delay: 0.0,
usingSpringWithDamping: 0.4,
initialSpringVelocity: 0.0,
animations: {
fromView.transform = CGAffineTransform(
scaleX: finalFrame.width / initialFrame.width,
y: finalFrame.height / initialFrame.height
)
fromView.center = CGPoint(x: finalFrame.midX, y: finalFrame.midY)
},
completion: { _ in
transitionContext.completeTransition(true)
}
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment