Skip to content

Instantly share code, notes, and snippets.

View RaajeevChandran's full-sized avatar

Raajeev Chandran RaajeevChandran

View GitHub Profile
class ViewController: UIViewController {
private let scrollView = UIScrollView()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
setupScrollView()
}
private func setupScrollView() {
class BottomSheetTransition: UIPercentDrivenInteractiveTransition {
private var dismissalAnimator: UIViewPropertyAnimator?
private var presentationAnimator: UIViewPropertyAnimator?
private let animationDuration = 0.5
private let dampingRatio: Double = 0.9
var dismissFractionComplete: CGFloat {
class BottomSheetTransitioningDelegate: NSObject {
let transition: BottomSheetTransition
override init() {
self.transition = BottomSheetTransition()
}
}
extension BottomSheetTransitioningDelegate: UIViewControllerTransitioningDelegate {
class BottomSheetPresentationController: UIPresentationController {
private let dismissThreshold: CGFloat = 0.3
private let grabberView: UIView = {
let view = UIView()
view.frame.size = CGSize(width: 50, height: 3)
view.backgroundColor = .lightGray
return view
}()
override var frameOfPresentedViewInContainerView: CGRect {
guard let containerView, let presentedView else {
return super.frameOfPresentedViewInContainerView
}
let maximumWidth = containerView.bounds.width
let maximumHeight = containerView.frame.height - containerView.safeAreaInsets.top - containerView.safeAreaInsets.bottom
let fittingSize = CGSize(width: maximumWidth, height: UIView.layoutFittingCompressedSize.height)
override func presentationTransitionWillBegin() {
super.presentationTransitionWillBegin()
containerView?.addSubview(dimmedBackgroundView)
dimmedBackgroundView.backgroundColor = .black.withAlphaComponent(0.5)
presentedView?.addSubview(grabberView)
presentedViewController.transitionCoordinator?.animate(alongsideTransition: {
override func containerViewDidLayoutSubviews() {
super.containerViewDidLayoutSubviews()
guard let presentedView, let containerView else {
return
}
dimmedBackgroundView.frame = containerView.bounds
grabberView.frame.origin.y = 8
override func dismissalTransitionWillBegin() {
super.dismissalTransitionWillBegin()
presentedViewController.transitionCoordinator?.animate(alongsideTransition: { [weak self] _ in
guard let self else { return }
self.presentedView?.layer.cornerRadius = .zero
self.dimmedBackgroundView.backgroundColor = .clear
})
}
extension BottomSheetPresentationController {
private func setupInteraction() {
guard let presentedView = presentedView else {
return
}
func addGestureIfNeeded(_ gesture: UIGestureRecognizer, to view: UIView, delegate: UIGestureRecognizerDelegate? = nil) {
if let recognizers = view.gestureRecognizers, recognizers.contains(gesture) {
return
}
private func dismiss(withInteraction: Bool) {
transitioningDelegate?.transition.wantsInteractiveStart = withInteraction
presentedViewController.dismiss(animated: true)
}