123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- import UIKit
- public final class ActionSheetView: UIView {
- public static var `default`: ActionSheetView {
- return ActionSheetView()
- }
-
- private typealias ButtonAction = ((AlertAction) -> Void)
-
- public private(set) var alertActions: [AlertAction] = []
- public private(set) var cancelAction: AlertAction? = nil
- private var _cancelItem: AlertItem?
- private var _alertItems: [AlertItem] = []
-
- private var actions: [ButtonAction] = []
- private var viewNotReady = true
-
- var title: String = ""
- var message: String = ""
-
- override public func didMoveToWindow() {
- super.didMoveToWindow()
- guard viewNotReady else { return }
- constructViewHierarchy()
- activateConstraints()
- installTarget()
- backgroundColor = UIColor(r: 153, g: 153, b: 153)
- viewNotReady = false
- }
-
- private func constructViewHierarchy() {
- for item in _alertItems { addSubview(item) }
-
- guard let item = _cancelItem else { return }
- addSubview(item)
- }
-
- private func activateConstraints() {
- activateConstraintsCancelItem()
- activateConstraintsItems()
- activateConstraintsRootView()
- }
-
- func addAlertAction(_ action: AlertAction) {
- switch action.style {
- case .default, .custom:
- alertActions.append(action)
- _alertItems.append(action.style.item)
- case .cancel:
- cancelAction = action
- _cancelItem = action.style.item
- }
- }
-
- private func installTarget() {
- if cancelAction != nil {
- _cancelItem?.addTarget(self, action: #selector(cancelAction(btn:)), for: .touchUpInside)
- }
-
- for (i, item) in _alertItems.enumerated() {
- item.sign = i
- item.addTarget(self, action: #selector(alertAction), for: .touchUpInside)
- }
- }
-
- @objc private func alertAction(btn: UIButton) {
- guard let alertItem = btn as? AlertItem else { return }
- alertActions[alertItem.sign].handler?(alertItem)
-
- dismissSuperViewController()
- }
-
- @objc private func cancelAction(btn: UIButton) {
- guard let cancelItem = _cancelItem else { return }
- cancelAction?.handler?(cancelItem)
-
- dismissSuperViewController()
- }
-
- private func dismissSuperViewController() {
- guard let vc = getSuperViewController() else { return }
- vc.dismissController()
- }
- }
- fileprivate extension ActionSheetView {
- func activateConstraintsRootView() {
- guard let v = superview else { return }
- translatesAutoresizingMaskIntoConstraints = false
-
- NSLayoutConstraint.activate([
- bottomAnchor.constraint(equalTo: v.bottomAnchor),
- leadingAnchor.constraint(equalTo: v.leadingAnchor),
- trailingAnchor.constraint(equalTo: v.trailingAnchor)
- ])
- }
-
- func activateConstraintsCancelItem() {
- guard let alertAction = cancelAction,
- let cancelItem = _cancelItem else { return }
- cancelItem.translatesAutoresizingMaskIntoConstraints = false
- cancelItem.setTitle(alertAction.title, for: .normal)
-
- NSLayoutConstraint.activate([
- cancelItem.heightAnchor.constraint(equalToConstant: 44),
- cancelItem.leadingAnchor.constraint(equalTo: leadingAnchor),
- cancelItem.trailingAnchor.constraint(equalTo: trailingAnchor),
- cancelItem.bottomAnchor.constraint(equalTo: bottomAnchor)
- ])
- }
-
- func activateConstraintsItems() {
- guard !alertActions.isEmpty else { return }
- var last: UIButton? = _cancelItem
- var bottom: CGFloat = _cancelItem == nil ? 0 : -6
- for (alertAction, item) in zip(alertActions, _alertItems).reversed() {
- item.translatesAutoresizingMaskIntoConstraints = false
- item.setTitle(alertAction.title, for: .normal)
- NSLayoutConstraint.activate([
- item.heightAnchor.constraint(equalToConstant: 44),
- item.leadingAnchor.constraint(equalTo: leadingAnchor),
- item.trailingAnchor.constraint(equalTo: trailingAnchor),
- item.bottomAnchor.constraint(equalTo: last?.topAnchor ?? bottomAnchor, constant: bottom)
- ])
- last = item
- bottom = -1
- }
- NSLayoutConstraint.activate([topAnchor.constraint(equalTo: last!.topAnchor)])
- }
- }
- fileprivate extension AlertAction.Style {
- var item: AlertItem {
- switch self {
- case .cancel:
- return BottomCancelItem()
- case .default:
- return BottomDefaultItem()
- case let .custom(v):
- return v
- }
- }
- }
|