Dactyloidae/mobile/ios/Client/Frontend/Widgets/PhotonActionSheetAnimator.swift
2026-06-26 21:04:09 -07:00

79 lines
3.6 KiB
Swift

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import UIKit
class PhotonActionSheetAnimator: NSObject, UIViewControllerAnimatedTransitioning {
var presenting: Bool = false
let animationDuration = 0.4
lazy var shadow: UIView = {
let shadow = UIView()
shadow.backgroundColor = UIColor(white: 0, alpha: 0.5)
return shadow
}()
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let screens = (from: transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!, to: transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!)
guard let actionSheet = (self.presenting ? screens.to : screens.from) as? PhotonActionSheet else {
return
}
let bottomViewController = (self.presenting ? screens.from : screens.to) as UIViewController
animateWitVC(actionSheet, presentingVC: bottomViewController, transitionContext: transitionContext)
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return animationDuration
}
}
extension PhotonActionSheetAnimator: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
self.presenting = true
return self
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
self.presenting = false
return self
}
}
extension PhotonActionSheetAnimator {
fileprivate func animateWitVC(_ actionSheet: PhotonActionSheet, presentingVC viewController: UIViewController, transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
if presenting {
shadow.frame = containerView.bounds
containerView.addSubview(shadow)
actionSheet.view.frame = CGRect(origin: CGPoint(x: 0, y: containerView.frame.size.height), size: containerView.frame.size)
self.shadow.alpha = 0
containerView.addSubview(actionSheet.view)
actionSheet.view.layoutIfNeeded()
UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.3, options: [], animations: { () -> Void in
self.shadow.alpha = 1
actionSheet.view.frame = containerView.bounds
actionSheet.view.layoutIfNeeded()
}, completion: { (completed) -> Void in
transitionContext.completeTransition(completed)
})
} else {
UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0, usingSpringWithDamping: 1.2, initialSpringVelocity: 0.0, options: [], animations: { () -> Void in
self.shadow.alpha = 0
actionSheet.view.frame = CGRect(origin: CGPoint(x: 0, y: containerView.frame.size.height), size: containerView.frame.size)
actionSheet.view.layoutIfNeeded()
}, completion: { (completed) -> Void in
actionSheet.view.removeFromSuperview()
self.shadow.removeFromSuperview()
transitionContext.completeTransition(completed)
})
}
}
}