|
// Created by Caleb Davenport on 7/14/17. |
|
|
|
import UIKit |
|
|
|
final class ActionSheetPresentationController: UIPresentationController { |
|
|
|
// MARK: - Properties |
|
|
|
private var dimmingView: UIView! |
|
|
|
private var customPresentedView: UIView! |
|
|
|
override var presentedView: UIView? { |
|
return customPresentedView |
|
} |
|
|
|
override var frameOfPresentedViewInContainerView: CGRect { |
|
let size = customPresentedView.systemLayoutSizeFitting( |
|
containerView!.bounds.size, |
|
withHorizontalFittingPriority: UILayoutPriorityRequired, |
|
verticalFittingPriority: UILayoutPriorityFittingSizeLevel) |
|
|
|
let (slice, _) = containerView!.bounds.divided(atDistance: size.height, from: .maxYEdge) |
|
|
|
return slice |
|
} |
|
|
|
|
|
// MARK: - UIPresentationController |
|
|
|
override func presentationTransitionWillBegin() { |
|
super.presentationTransitionWillBegin() |
|
|
|
if dimmingView == nil { |
|
dimmingView = UIView() |
|
dimmingView.backgroundColor = UIColor(white: 0, alpha: 0.4) |
|
|
|
let cancelGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(cancel)) |
|
dimmingView.addGestureRecognizer(cancelGestureRecognizer) |
|
|
|
dimmingView.autoresizingMask = [.flexibleWidth, .flexibleHeight] |
|
dimmingView.frame = containerView!.bounds |
|
containerView!.addSubview(dimmingView) |
|
} |
|
|
|
if customPresentedView == nil { |
|
let dismissButton = ActionSheetPresentationControllerDismissButton() |
|
dismissButton.addTarget(self, action: #selector(cancel), for: .touchUpInside) |
|
dismissButton.setContentHuggingPriority(UILayoutPriorityDefaultHigh, for: .vertical) |
|
|
|
let dismissButtonSectionView = ActionSheetPresentationControllerSectionView() |
|
dismissButton.translatesAutoresizingMaskIntoConstraints = false |
|
dismissButtonSectionView.addSubview(dismissButton) |
|
|
|
let presentedViewControllerSectionView = ActionSheetPresentationControllerSectionView() |
|
presentedViewController.view.translatesAutoresizingMaskIntoConstraints = false |
|
presentedViewControllerSectionView.addSubview(presentedViewController.view) |
|
|
|
NSLayoutConstraint.activate([ |
|
dismissButton.leadingAnchor.constraint(equalTo: dismissButtonSectionView.leadingAnchor), |
|
dismissButton.trailingAnchor.constraint(equalTo: dismissButtonSectionView.trailingAnchor), |
|
dismissButton.topAnchor.constraint(equalTo: dismissButtonSectionView.topAnchor), |
|
dismissButton.bottomAnchor.constraint(equalTo: dismissButtonSectionView.bottomAnchor), |
|
|
|
presentedViewController.view.leadingAnchor.constraint(equalTo: presentedViewControllerSectionView.leadingAnchor), |
|
presentedViewController.view.trailingAnchor.constraint(equalTo: presentedViewControllerSectionView.trailingAnchor), |
|
presentedViewController.view.topAnchor.constraint(equalTo: presentedViewControllerSectionView.topAnchor), |
|
presentedViewController.view.bottomAnchor.constraint(equalTo: presentedViewControllerSectionView.bottomAnchor)]) |
|
|
|
let stackView = UIStackView(arrangedSubviews: [presentedViewControllerSectionView, dismissButtonSectionView]) |
|
stackView.autoresizingMask = [.flexibleWidth, .flexibleTopMargin] |
|
stackView.axis = .vertical |
|
stackView.isLayoutMarginsRelativeArrangement = true |
|
stackView.spacing = 10 |
|
stackView.layoutMargins = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10) |
|
|
|
customPresentedView = stackView |
|
} |
|
|
|
dimmingView.alpha = 0 |
|
|
|
presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in |
|
self.dimmingView.alpha = 1 |
|
}) |
|
} |
|
|
|
override func dismissalTransitionWillBegin() { |
|
presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in |
|
self.dimmingView.alpha = 0 |
|
}) |
|
} |
|
|
|
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { |
|
super.viewWillTransition(to: size, with: coordinator) |
|
|
|
coordinator.animate(alongsideTransition: { _ in |
|
self.customPresentedView.frame = self.frameOfPresentedViewInContainerView |
|
}) |
|
} |
|
|
|
|
|
// MARK: - Private |
|
|
|
@objc private func cancel() { |
|
presentedViewController.dismiss(animated: true, completion: nil) |
|
} |
|
} |