// // TooltipAlertViewController.swift // VDS // // Created by Matt Bruce on 4/14/23. // import Foundation import UIKit import Combine import VDSColorTokens open class TooltipAlertViewController: UIViewController, Surfaceable { //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- private var onClickSubscriber: AnyCancellable? { willSet { if let onClickSubscriber { onClickSubscriber.cancel() } } } private var scrollView = UIScrollView().with { $0.translatesAutoresizingMaskIntoConstraints = false $0.backgroundColor = .clear $0.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -5) } private let containerView = View().with { $0.layer.cornerRadius = 8 $0.layer.shadowColor = UIColor.black.cgColor $0.layer.shadowOpacity = 0.5 $0.layer.shadowOffset = CGSize.zero $0.layer.shadowRadius = 5 } private var line = Line().with { instance in instance.lineViewColorConfig = SurfaceColorConfiguration(VDSColor.elementsLowContrastOnLight, VDSColor.elementsLowContrastOnLight).eraseToAnyColorable() } //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- open var surface: Surface = .light { didSet { updateView() }} open var titleText: String = "" { didSet { updateView() }} open var titleLabel = Label().with { label in label.textStyle = .boldTitleMedium } open var contentText: String = "" { didSet { updateView() }} open var contentLabel = Label().with { label in label.textStyle = .bodyMedium } open var closeButtonText: String = "Close" { didSet { updateView() }} open lazy var closeButton: UIButton = { let button = UIButton(type: .system) button.backgroundColor = .clear button.setTitle("Close", for: .normal) button.titleLabel?.font = TextStyle.bodyLarge.font button.translatesAutoresizingMaskIntoConstraints = false onClickSubscriber = button.publisher(for: .touchUpInside).sink {[weak self] button in guard let self else { return } self.dismiss(animated: true, completion: nil) } return button }() //-------------------------------------------------- // MARK: - Configuration //-------------------------------------------------- private let containerViewBackgroundColorConfiguration = SurfaceColorConfiguration().with { instance in instance.lightColor = .white instance.darkColor = .black } private let backgroundColorConfiguration = SurfaceColorConfiguration(VDSColor.backgroundPrimaryDark, VDSColor.backgroundPrimaryLight) private let closeButtonTextColorConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark) //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- open override func viewDidLoad() { super.viewDidLoad() isModalInPresentation = true setup() } open func setup() { scrollView.addSubview(titleLabel) scrollView.addSubview(contentLabel) containerView.addSubview(scrollView) containerView.addSubview(line) containerView.addSubview(closeButton) view.addSubview(containerView) NSLayoutConstraint.activate([ containerView.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: VDSLayout.Spacing.space8X.value), containerView.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -VDSLayout.Spacing.space8X.value), containerView.topAnchor.constraint(greaterThanOrEqualTo: view.topAnchor), containerView.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor), containerView.heightAnchor.constraint(equalToConstant: 312), containerView.widthAnchor.constraint(equalToConstant: 296), containerView.centerXAnchor.constraint(equalTo: view.centerXAnchor), containerView.centerYAnchor.constraint(equalTo: view.centerYAnchor), scrollView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: VDSLayout.Spacing.space4X.value), scrollView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: VDSLayout.Spacing.space4X.value), scrollView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -VDSLayout.Spacing.space4X.value), scrollView.bottomAnchor.constraint(equalTo: line.topAnchor, constant: -VDSLayout.Spacing.space4X.value), titleLabel.topAnchor.constraint(equalTo: scrollView.topAnchor), titleLabel.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor), titleLabel.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor), titleLabel.widthAnchor.constraint(equalTo: scrollView.widthAnchor), contentLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: VDSLayout.Spacing.space1X.value), contentLabel.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor), contentLabel.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor), contentLabel.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor), contentLabel.widthAnchor.constraint(equalTo: scrollView.widthAnchor), line.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), line.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), closeButton.topAnchor.constraint(equalTo: line.bottomAnchor), closeButton.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), closeButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), closeButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor), closeButton.heightAnchor.constraint(equalToConstant: 44.0) ]) } open func updateView() { view.backgroundColor = backgroundColorConfiguration.getColor(self).withAlphaComponent(0.3) containerView.backgroundColor = containerViewBackgroundColorConfiguration.getColor(self) scrollView.indicatorStyle = surface == .light ? .black : .white titleLabel.surface = surface contentLabel.surface = surface line.surface = surface titleLabel.text = titleText contentLabel.text = contentText titleLabel.sizeToFit() contentLabel.sizeToFit() let closeButtonTextColor = closeButtonTextColorConfiguration.getColor(self) closeButton.setTitleColor(closeButtonTextColor, for: .normal) closeButton.setTitleColor(closeButtonTextColor, for: .highlighted) closeButton.setTitle(closeButtonText, for: .normal) } }