updated tooltip to accept a view or title or content text
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
fb9855593f
commit
c02fd2241e
@ -20,8 +20,9 @@ public class TooltipLabelAttribute: ActionLabelAttributeModel, TooltipLaunchable
|
||||
public var surface: Surface = .light
|
||||
public var accessibleText: String? = "Tool Tip"
|
||||
public var closeButtonText: String = "Close"
|
||||
public var title: String
|
||||
public var content: String
|
||||
public var title: String?
|
||||
public var content: String?
|
||||
public var contentView: UIView?
|
||||
|
||||
public func setAttribute(on attributedString: NSMutableAttributedString) {
|
||||
//update the location
|
||||
@ -65,7 +66,7 @@ public class TooltipLabelAttribute: ActionLabelAttributeModel, TooltipLaunchable
|
||||
addHandler(on: attributedString)
|
||||
}
|
||||
|
||||
public init(id: UUID = UUID(), action: PassthroughSubject<Void, Never> = PassthroughSubject<Void, Never>(), subscriber: AnyCancellable? = nil, surface: Surface, accessibleText: String? = nil, closeButtonText: String = "Close", title: String, content: String) {
|
||||
public init(id: UUID = UUID(), action: PassthroughSubject<Void, Never> = PassthroughSubject<Void, Never>(), subscriber: AnyCancellable? = nil, surface: Surface, accessibleText: String? = nil, closeButtonText: String = "Close", title: String? = nil, content: String? = nil, contentView: UIView? = nil) {
|
||||
self.id = id
|
||||
self.action = action
|
||||
self.subscriber = subscriber
|
||||
@ -74,13 +75,14 @@ public class TooltipLabelAttribute: ActionLabelAttributeModel, TooltipLaunchable
|
||||
self.closeButtonText = closeButtonText
|
||||
self.title = title
|
||||
self.content = content
|
||||
|
||||
self.contentView = contentView
|
||||
//create the tooltip click event
|
||||
self.subscriber = action.sink { [weak self] in
|
||||
guard let self else { return }
|
||||
self.presentTooltip(surface: self.surface,
|
||||
title: self.title,
|
||||
content: self.content,
|
||||
contentView: contentView,
|
||||
closeButtonText: self.closeButtonText)
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,6 +151,8 @@ open class EntryField: Control, Changeable {
|
||||
|
||||
open var tooltipContent: String? { didSet { setNeedsUpdate() }}
|
||||
|
||||
open var tooltipContentView: UIView? { didSet { setNeedsUpdate() }}
|
||||
|
||||
open var transparentBackground: Bool = false { didSet { setNeedsUpdate() }}
|
||||
|
||||
open var width: CGFloat? { didSet { setNeedsUpdate() }}
|
||||
@ -293,7 +295,7 @@ open class EntryField: Control, Changeable {
|
||||
}
|
||||
|
||||
if let tooltipTitle, let tooltipContent {
|
||||
attributes.append(TooltipLabelAttribute(surface: surface, title: tooltipTitle, content: tooltipContent))
|
||||
attributes.append(TooltipLabelAttribute(surface: surface, title: tooltipTitle, content: tooltipContent, contentView: tooltipContentView))
|
||||
}
|
||||
|
||||
//set the titleLabel
|
||||
|
||||
@ -50,10 +50,12 @@ open class Tooltip: Control, TooltipLaunchable {
|
||||
|
||||
open var size: Size = .medium { didSet { setNeedsUpdate() }}
|
||||
|
||||
open var title: String = "" { didSet { setNeedsUpdate() }}
|
||||
|
||||
open var content: String = "" { didSet { setNeedsUpdate() }}
|
||||
open var title: String? { didSet { setNeedsUpdate() }}
|
||||
|
||||
open var content: String? { didSet { setNeedsUpdate() }}
|
||||
|
||||
open var contentView: UIView? { didSet { setNeedsUpdate() }}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Configuration
|
||||
//--------------------------------------------------
|
||||
@ -132,6 +134,7 @@ open class Tooltip: Control, TooltipLaunchable {
|
||||
self.presentTooltip(surface: tooltip.surface,
|
||||
title: tooltip.title,
|
||||
content: tooltip.content,
|
||||
contentView: tooltip.contentView,
|
||||
closeButtonText: tooltip.closeButtonText)
|
||||
})
|
||||
}
|
||||
@ -160,8 +163,13 @@ open class Tooltip: Control, TooltipLaunchable {
|
||||
//get the color for the image
|
||||
let imageColor = iconColorConfiguration.getColor(self)
|
||||
imageView.image = infoImage.withTintColor(imageColor)
|
||||
|
||||
accessibilityLabel = "Tooltip: \(title)"
|
||||
var label = title
|
||||
if label == nil {
|
||||
label = content
|
||||
}
|
||||
if let label {
|
||||
accessibilityLabel = "Tooltip: \(label)"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import UIKit
|
||||
import Combine
|
||||
import VDSColorTokens
|
||||
|
||||
open class TooltipAlertViewController: UIViewController, Surfaceable {
|
||||
open class TooltipAlertViewController: UIViewController, Surfaceable, UIScrollViewDelegate {
|
||||
|
||||
/// Set of Subscribers for any Publishers for this Control
|
||||
public var subscribers = Set<AnyCancellable>()
|
||||
@ -35,8 +35,15 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
|
||||
$0.layer.cornerRadius = 8
|
||||
}
|
||||
|
||||
private let containerView = View()
|
||||
public var contentView: UIView? = nil
|
||||
|
||||
private let contentStackView = UIStackView().with {
|
||||
$0.translatesAutoresizingMaskIntoConstraints = false
|
||||
$0.axis = .vertical
|
||||
$0.distribution = .fillProportionally
|
||||
$0.spacing = 0
|
||||
}
|
||||
|
||||
private var line = Line().with { instance in
|
||||
instance.lineViewColorConfiguration = SurfaceColorConfiguration(VDSColor.elementsLowcontrastOnlight, VDSColor.elementsLowcontrastOndark).eraseToAnyColorable()
|
||||
}
|
||||
@ -45,12 +52,12 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
open var surface: Surface = .light { didSet { updateView() }}
|
||||
open var titleText: String = "" { 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 contentText: String? { didSet { updateView() }}
|
||||
open var contentLabel = Label().with { label in
|
||||
label.textStyle = .bodyLarge
|
||||
}
|
||||
@ -79,6 +86,9 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
|
||||
private let closeButtonTextColorConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark)
|
||||
|
||||
private let containerViewInset = VDSLayout.Spacing.space4X.value
|
||||
private var containerBottomConstraint: NSLayoutConstraint?
|
||||
private var containerHeightConstraint: NSLayoutConstraint?
|
||||
private var contentStackViewBottomConstraint: NSLayoutConstraint?
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
@ -89,7 +99,6 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
|
||||
}
|
||||
|
||||
open func setup() {
|
||||
|
||||
//left-right swipe
|
||||
view.publisher(for: UISwipeGestureRecognizer().with{ $0.direction = .right })
|
||||
.sink { [weak self] swipe in
|
||||
@ -111,9 +120,9 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
|
||||
self.dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
containerView.addSubview(titleLabel)
|
||||
containerView.addSubview(contentLabel)
|
||||
scrollView.addSubview(containerView)
|
||||
contentStackView.addArrangedSubview(titleLabel)
|
||||
contentStackView.addArrangedSubview(contentLabel)
|
||||
scrollView.addSubview(contentStackView)
|
||||
modalView.addSubview(scrollView)
|
||||
modalView.addSubview(line)
|
||||
modalView.addSubview(closeButton)
|
||||
@ -134,14 +143,6 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
|
||||
scrollView.trailingAnchor.constraint(equalTo: modalView.trailingAnchor),
|
||||
scrollView.bottomAnchor.constraint(equalTo: line.topAnchor),
|
||||
|
||||
// Constraints for the container view
|
||||
containerView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0),
|
||||
containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -containerViewInset),
|
||||
containerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: containerViewInset),
|
||||
containerView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -containerViewInset),
|
||||
containerView.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: -(containerViewInset * 2)),
|
||||
containerView.heightAnchor.constraint(greaterThanOrEqualTo: scrollView.heightAnchor, constant: -(containerViewInset * 2)),
|
||||
|
||||
line.leadingAnchor.constraint(equalTo: modalView.leadingAnchor),
|
||||
line.trailingAnchor.constraint(equalTo: modalView.trailingAnchor),
|
||||
|
||||
@ -151,14 +152,12 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
|
||||
closeButton.bottomAnchor.constraint(equalTo: modalView.bottomAnchor),
|
||||
closeButton.heightAnchor.constraint(equalToConstant: 44.0),
|
||||
|
||||
// Constraints on labels
|
||||
titleLabel.topAnchor.constraint(equalTo: containerView.topAnchor),
|
||||
titleLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
|
||||
titleLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
|
||||
contentLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: VDSLayout.Spacing.space1X.value),
|
||||
contentLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
|
||||
contentLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
|
||||
contentLabel.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
|
||||
contentStackView.topAnchor.constraint(equalTo: scrollView.topAnchor),
|
||||
contentStackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: containerViewInset),
|
||||
contentStackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -containerViewInset),
|
||||
contentStackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -containerViewInset),
|
||||
contentStackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: -(containerViewInset * 2)),
|
||||
contentStackView.heightAnchor.constraint(greaterThanOrEqualTo: scrollView.heightAnchor, constant: -(containerViewInset * 2))
|
||||
|
||||
])
|
||||
}
|
||||
@ -168,18 +167,57 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
|
||||
modalView.backgroundColor = containerViewBackgroundColorConfiguration.getColor(self)
|
||||
scrollView.indicatorStyle = surface == .light ? .black : .white
|
||||
|
||||
titleLabel.removeFromSuperview()
|
||||
contentLabel.removeFromSuperview()
|
||||
contentView?.removeFromSuperview()
|
||||
|
||||
titleLabel.surface = surface
|
||||
contentLabel.surface = surface
|
||||
line.surface = surface
|
||||
|
||||
titleLabel.text = titleText
|
||||
contentLabel.text = contentText
|
||||
|
||||
titleLabel.sizeToFit()
|
||||
contentLabel.sizeToFit()
|
||||
|
||||
|
||||
var addedTitle = false
|
||||
|
||||
if let titleText, !titleText.isEmpty {
|
||||
contentStackView.addArrangedSubview(titleLabel)
|
||||
addedTitle = true
|
||||
}
|
||||
|
||||
var addedContent = false
|
||||
if let contentText, !contentText.isEmpty {
|
||||
contentStackView.addArrangedSubview(contentLabel)
|
||||
addedContent = true
|
||||
} else if let contentView {
|
||||
contentView.translatesAutoresizingMaskIntoConstraints = false
|
||||
if var surfaceable = contentView as? Surfaceable {
|
||||
surfaceable.surface = surface
|
||||
}
|
||||
let wrapper = View()
|
||||
wrapper.addSubview(contentView)
|
||||
contentView.pinTop()
|
||||
contentView.pinLeading()
|
||||
contentView.pinBottom()
|
||||
contentView.pinTrailingLessThanOrEqualTo()
|
||||
contentView.setNeedsLayout()
|
||||
contentStackView.addArrangedSubview(wrapper)
|
||||
addedContent = true
|
||||
}
|
||||
|
||||
if addedTitle && addedContent {
|
||||
contentStackView.setCustomSpacing(VDSLayout.Spacing.space1X.value, after: titleLabel)
|
||||
}
|
||||
|
||||
let closeButtonTextColor = closeButtonTextColorConfiguration.getColor(self)
|
||||
closeButton.setTitleColor(closeButtonTextColor, for: .normal)
|
||||
closeButton.setTitleColor(closeButtonTextColor, for: .highlighted)
|
||||
closeButton.setTitle(closeButtonText, for: .normal)
|
||||
|
||||
scrollView.layoutIfNeeded()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,16 +9,17 @@ import Foundation
|
||||
import UIKit
|
||||
|
||||
public protocol TooltipLaunchable {
|
||||
func presentTooltip(surface: Surface, title: String, content: String, closeButtonText: String)
|
||||
func presentTooltip(surface: Surface, title: String?, content: String?, contentView: UIView?, closeButtonText: String)
|
||||
}
|
||||
|
||||
extension TooltipLaunchable {
|
||||
public func presentTooltip(surface: Surface, title: String, content: String, closeButtonText: String = "Close") {
|
||||
public func presentTooltip(surface: Surface, title: String?, content: String?, contentView: UIView? = nil, closeButtonText: String = "Close") {
|
||||
if let presenting = UIApplication.topViewController() {
|
||||
let tooltipViewController = TooltipAlertViewController(nibName: nil, bundle: nil).with {
|
||||
$0.surface = surface
|
||||
$0.titleText = title
|
||||
$0.contentText = content
|
||||
$0.contentView = contentView
|
||||
$0.closeButtonText = closeButtonText
|
||||
$0.modalPresentationStyle = .overCurrentContext
|
||||
$0.modalTransitionStyle = .crossDissolve
|
||||
|
||||
@ -36,10 +36,12 @@ open class TrailingTooltipLabel: View, TooltipLaunchable {
|
||||
|
||||
open var tooltipCloseButtonText: String = "Close" { didSet { setNeedsUpdate() } }
|
||||
|
||||
open var tooltipTitle: String = "" { didSet { setNeedsUpdate() } }
|
||||
open var tooltipTitle: String? { didSet { setNeedsUpdate() } }
|
||||
|
||||
open var tooltipContent: String = "" { didSet { setNeedsUpdate() } }
|
||||
open var tooltipContent: String? { didSet { setNeedsUpdate() } }
|
||||
|
||||
open var tooltipContentView: UIView? { didSet { setNeedsUpdate() } }
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Overrides
|
||||
//--------------------------------------------------
|
||||
@ -70,8 +72,8 @@ open class TrailingTooltipLabel: View, TooltipLaunchable {
|
||||
label.disabled = disabled
|
||||
|
||||
//add tooltip
|
||||
if let labelText, !labelText.isEmpty, !tooltipTitle.isEmpty, !tooltipContent.isEmpty {
|
||||
label.addTooltip(model: .init(surface: surface, closeButtonText: tooltipCloseButtonText, title: tooltipTitle, content: tooltipContent))
|
||||
if let labelText, !labelText.isEmpty {
|
||||
label.addTooltip(model: .init(surface: surface, closeButtonText: tooltipCloseButtonText, title: tooltipTitle, content: tooltipContent, contentView: tooltipContentView))
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,14 +97,15 @@ extension Label {
|
||||
public struct TooltipModel {
|
||||
public var surface: Surface
|
||||
public var closeButtonText: String
|
||||
public var title: String
|
||||
public var content: String
|
||||
|
||||
public init(surface: Surface = .light, closeButtonText: String = "Close", title: String, content: 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
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,7 +124,8 @@ extension Label {
|
||||
let tooltip = TooltipLabelAttribute(surface: surface,
|
||||
closeButtonText: model.closeButtonText,
|
||||
title: model.title,
|
||||
content: model.content)
|
||||
content: model.content,
|
||||
contentView: model.contentView)
|
||||
newAttributes.append(tooltip)
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user