Maintain velocity when dismissing sheet

This commit is contained in:
Shadowfacts 2020-02-22 15:21:08 -05:00
parent 6ee1ad24ec
commit 6926446c4e
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
2 changed files with 33 additions and 5 deletions

View File

@ -32,15 +32,28 @@ class SheetContainerDismissAnimationController: NSObject, UIViewControllerAnimat
container.addSubview(fromVC.view) container.addSubview(fromVC.view)
let duration = transitionDuration(using: transitionContext) let duration = transitionDuration(using: transitionContext)
UIView.animate(withDuration: duration, animations: { let animator: UIViewPropertyAnimator
if let initialVelocity = fromVC.dismissAnimationInitialVelocity {
let vector = CGVector(dx: initialVelocity, dy: 0)
let parameters = UISpringTimingParameters(dampingRatio: 1, initialVelocity: vector)
animator = UIViewPropertyAnimator(duration: duration, timingParameters: parameters)
} else {
animator = UIViewPropertyAnimator(duration: duration, curve: .easeOut)
}
animator.addAnimations {
dimmingView.frame = container.bounds dimmingView.frame = container.bounds
dimmingView.alpha = 0 dimmingView.alpha = 0
fromVC.view.transform = CGAffineTransform(translationX: 0, y: fromVC.content.view.bounds.height) fromVC.view.transform = CGAffineTransform(translationX: 0, y: fromVC.content.view.bounds.height)
}, completion: { (finished) in }
animator.addCompletion { (position) in
dimmingView.removeFromSuperview() dimmingView.removeFromSuperview()
transitionContext.completeTransition(!transitionContext.transitionWasCancelled) transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}) }
animator.startAnimation()
} }
} }

View File

@ -59,6 +59,9 @@ open class SheetContainerViewController: UIViewController {
var initialScrollViewContentOffset: CGPoint? var initialScrollViewContentOffset: CGPoint?
var scrollViewIsMovingSheet = false var scrollViewIsMovingSheet = false
public var dismissAtBottomDetent = true
var dismissAnimationInitialVelocity: CGFloat?
public init(content: UIViewController) { public init(content: UIViewController) {
self.content = content self.content = content
@ -204,10 +207,22 @@ open class SheetContainerViewController: UIViewController {
return return
} }
let springVelocity: CGFloat
let springDistance = abs(topConstraint.constant - springToDetent.1)
if springDistance != 0 {
springVelocity = velocity / springDistance
} else {
springVelocity = 0
}
if dismissAtBottomDetent, springToDetent.0 == .bottom {
dismissAnimationInitialVelocity = springVelocity
dismiss(animated: true)
return
}
if delegate?.sheetContainer(self, willSnapToDetent: springToDetent.0) ?? true { if delegate?.sheetContainer(self, willSnapToDetent: springToDetent.0) ?? true {
let springDistance = abs(topConstraint.constant - springToDetent.1)
self.topConstraint.constant = springToDetent.1 self.topConstraint.constant = springToDetent.1
let springVelocity = velocity / springDistance
UIView.animate(withDuration: 0.35, delay: 0, usingSpringWithDamping: 0.75, initialSpringVelocity: springVelocity, animations: { UIView.animate(withDuration: 0.35, delay: 0, usingSpringWithDamping: 0.75, initialSpringVelocity: springVelocity, animations: {
self.view.layoutIfNeeded() self.view.layoutIfNeeded()