158 lines
5.3 KiB
Swift
158 lines
5.3 KiB
Swift
//
|
|
// TrailingTooltipLabel.swift
|
|
// VDS
|
|
//
|
|
// Created by Matt Bruce on 4/14/23.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
import Combine
|
|
|
|
@objc(VDSTrailingTooltipLabel)
|
|
open class TrailingTooltipLabel: View, TooltipLaunchable {
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Initializers
|
|
//--------------------------------------------------
|
|
required public init() {
|
|
super.init(frame: .zero)
|
|
}
|
|
|
|
public override init(frame: CGRect) {
|
|
super.init(frame: .zero)
|
|
}
|
|
|
|
public required init?(coder: NSCoder) {
|
|
super.init(coder: coder)
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Private Properties
|
|
//--------------------------------------------------
|
|
private let tooltipAction = PassthroughSubject<Void, Never>()
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Public Properties
|
|
//--------------------------------------------------
|
|
open var label = Label()
|
|
|
|
open var labelText: String? { didSet { setNeedsUpdate() }}
|
|
|
|
open var labelAttributes: [any LabelAttributeModel]? { didSet { setNeedsUpdate() } }
|
|
|
|
open var labelTextStyle: TextStyle = .defaultStyle { didSet { setNeedsUpdate() } }
|
|
|
|
open var labelTextPosition: TextPosition = .left { didSet { setNeedsUpdate() } }
|
|
|
|
public lazy var textColorConfiguration: AnyColorable = {
|
|
label.textColorConfiguration
|
|
}() { didSet { setNeedsUpdate() }}
|
|
|
|
open var tooltipCloseButtonText: String = "Close" { didSet { setNeedsUpdate() } }
|
|
|
|
open var tooltipTitle: String? { didSet { setNeedsUpdate() } }
|
|
|
|
open var tooltipContent: String? { didSet { setNeedsUpdate() } }
|
|
|
|
open var tooltipContentView: UIView? { didSet { setNeedsUpdate() } }
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Overrides
|
|
//--------------------------------------------------
|
|
/// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations.
|
|
open override func setup() {
|
|
super.setup()
|
|
|
|
addSubview(label)
|
|
label.pinToSuperView()
|
|
|
|
//create the tooltip click event
|
|
tooltipAction.sink { [weak self] in
|
|
guard let self else { return }
|
|
self.presentTooltip(surface: self.surface,
|
|
title: self.tooltipTitle,
|
|
content: self.tooltipContent,
|
|
closeButtonText: self.tooltipCloseButtonText,
|
|
presenter: self)
|
|
}.store(in: &subscribers)
|
|
}
|
|
|
|
/// Used to make changes to the View based off a change events or from local properties.
|
|
open override func updateView() {
|
|
super.updateView()
|
|
|
|
label.text = labelText
|
|
label.textStyle = labelTextStyle
|
|
label.textPosition = labelTextPosition
|
|
label.attributes = labelAttributes
|
|
label.surface = surface
|
|
label.isEnabled = isEnabled
|
|
|
|
//add tooltip
|
|
if let labelText, !labelText.isEmpty {
|
|
label.addTooltip(model: .init(surface: surface, closeButtonText: tooltipCloseButtonText, title: tooltipTitle, content: tooltipContent, contentView: tooltipContentView))
|
|
}
|
|
}
|
|
|
|
/// Resets to default settings.
|
|
open override func reset() {
|
|
super.reset()
|
|
shouldUpdateView = false
|
|
labelText = nil
|
|
labelAttributes = nil
|
|
labelTextStyle = .defaultStyle
|
|
labelTextPosition = .left
|
|
tooltipCloseButtonText = "Close"
|
|
tooltipTitle = ""
|
|
tooltipContent = ""
|
|
shouldUpdateView = true
|
|
setNeedsUpdate()
|
|
}
|
|
}
|
|
|
|
|
|
extension Label {
|
|
public struct TooltipModel {
|
|
/// Current Surface and this is used to pass down to child objects that implement Surfacable
|
|
public var surface: Surface
|
|
public var closeButtonText: String
|
|
public var title: String?
|
|
public var content: String?
|
|
public var contentView: UIView?
|
|
public init(surface: Surface = .light, closeButtonText: String = "Close", title: String?, content: String?, contentView: UIView?) {
|
|
self.surface = surface
|
|
self.closeButtonText = closeButtonText
|
|
self.title = title
|
|
self.content = content
|
|
self.contentView = contentView
|
|
}
|
|
}
|
|
|
|
public func addTooltip(model: TooltipModel) {
|
|
|
|
var newAttributes: [any LabelAttributeModel] = []
|
|
if let attributes {
|
|
attributes.forEach { attribute in
|
|
if type(of: attribute) != TooltipLabelAttribute.self {
|
|
newAttributes.append(attribute)
|
|
}
|
|
}
|
|
}
|
|
|
|
if let text = text, !text.isEmpty {
|
|
let tooltip = TooltipLabelAttribute(surface: surface,
|
|
closeButtonText: model.closeButtonText,
|
|
title: model.title,
|
|
content: model.content,
|
|
contentView: model.contentView,
|
|
presenter: self)
|
|
newAttributes.append(tooltip)
|
|
}
|
|
|
|
if !newAttributes.isEmpty {
|
|
attributes = newAttributes
|
|
}
|
|
}
|
|
}
|