// // TooltipAlertViewController.swift // VDS // // Created by Matt Bruce on 4/14/23. // import Foundation import UIKit import Combine import VDSColorTokens open class TooltipAlertViewController: UIViewController, Surfaceable { /// Set of Subscribers for any Publishers for this Control. open var subscribers = Set() //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- private var onClickSubscriber: AnyCancellable? { willSet { if let onClickSubscriber { onClickSubscriber.cancel() } } } private let tooltipDialog = TooltipDialog() //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- /// Current Surface and this is used to pass down to child objects that implement Surfacable open var surface: Surface = .light { didSet { updateView() }} open var titleText: String? { didSet { updateView() }} open var contentText: String? { didSet { updateView() }} open var contentView: UIView? { didSet { updateView() }} open var closeButtonText: String = "Close" { didSet { updateView() }} open var presenter: UIView? { didSet { updateView() }} //-------------------------------------------------- // MARK: - Configuration //-------------------------------------------------- private let backgroundColorConfiguration = SurfaceColorConfiguration(VDSColor.backgroundPrimaryDark, VDSColor.backgroundPrimaryLight) //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- open override func viewDidLoad() { super.viewDidLoad() isModalInPresentation = true setup() } open override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) UIAccessibility.post(notification: .screenChanged, argument: tooltipDialog) } private func dismiss() { dismiss(animated: true) { [weak self] in guard let self, let presenter else { return } UIAccessibility.post(notification: .layoutChanged, argument: presenter) } } open func setup() { view.accessibilityElements = [tooltipDialog] //left-right swipe view.publisher(for: UISwipeGestureRecognizer().with{ $0.direction = .right }) .sink { [weak self] swipe in guard let self else { return } self.dismiss() }.store(in: &subscribers) //tapping in background view.publisher(for: UITapGestureRecognizer().with{ $0.numberOfTapsRequired = 1 }) .sink { [weak self] swipe in guard let self else { return } self.dismiss() }.store(in: &subscribers) //clicking button onClickSubscriber = tooltipDialog.closeButton.publisher(for: .touchUpInside) .sink {[weak self] button in guard let self else { return } self.dismiss() } view.addSubview(tooltipDialog) // Activate constraints NSLayoutConstraint.activate([ // Constraints for the floating modal view tooltipDialog.centerXAnchor.constraint(equalTo: view.centerXAnchor), tooltipDialog.centerYAnchor.constraint(equalTo: view.centerYAnchor), tooltipDialog.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor), tooltipDialog.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor), tooltipDialog.topAnchor.constraint(greaterThanOrEqualTo: view.topAnchor), tooltipDialog.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor) ]) } /// Used to make changes to the View based off a change events or from local properties. open func updateView() { view.backgroundColor = backgroundColorConfiguration.getColor(self).withAlphaComponent(0.3) tooltipDialog.surface = surface tooltipDialog.titleText = titleText tooltipDialog.contentText = contentText tooltipDialog.contentView = contentView tooltipDialog.closeButtonText = closeButtonText } }