Merge branch 'mbruce/bugfixes' into 'develop'

updated eyebrow to be defaulted to bold

See merge request BPHV_MIPS/vds_ios!87
This commit is contained in:
Bruce, Matt R 2023-06-30 20:58:20 +00:00
commit 35370ce8d1
9 changed files with 164 additions and 82 deletions

View File

@ -1111,7 +1111,7 @@
BUILD_LIBRARY_FOR_DISTRIBUTION = YES; BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
CODE_SIGN_IDENTITY = ""; CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 25; CURRENT_PROJECT_VERSION = 26;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
@ -1148,7 +1148,7 @@
BUILD_LIBRARY_FOR_DISTRIBUTION = YES; BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
CODE_SIGN_IDENTITY = ""; CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 25; CURRENT_PROJECT_VERSION = 26;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;

View File

@ -20,8 +20,9 @@ public class TooltipLabelAttribute: ActionLabelAttributeModel, TooltipLaunchable
public var surface: Surface = .light public var surface: Surface = .light
public var accessibleText: String? = "Tool Tip" public var accessibleText: String? = "Tool Tip"
public var closeButtonText: String = "Close" public var closeButtonText: String = "Close"
public var title: String public var title: String?
public var content: String public var content: String?
public var contentView: UIView?
public func setAttribute(on attributedString: NSMutableAttributedString) { public func setAttribute(on attributedString: NSMutableAttributedString) {
//update the location //update the location
@ -65,7 +66,7 @@ public class TooltipLabelAttribute: ActionLabelAttributeModel, TooltipLaunchable
addHandler(on: attributedString) 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.id = id
self.action = action self.action = action
self.subscriber = subscriber self.subscriber = subscriber
@ -74,13 +75,14 @@ public class TooltipLabelAttribute: ActionLabelAttributeModel, TooltipLaunchable
self.closeButtonText = closeButtonText self.closeButtonText = closeButtonText
self.title = title self.title = title
self.content = content self.content = content
self.contentView = contentView
//create the tooltip click event //create the tooltip click event
self.subscriber = action.sink { [weak self] in self.subscriber = action.sink { [weak self] in
guard let self else { return } guard let self else { return }
self.presentTooltip(surface: self.surface, self.presentTooltip(surface: self.surface,
title: self.title, title: self.title,
content: self.content, content: self.content,
contentView: contentView,
closeButtonText: self.closeButtonText) closeButtonText: self.closeButtonText)
} }
} }

View File

@ -151,6 +151,8 @@ open class EntryField: Control, Changeable {
open var tooltipContent: String? { didSet { setNeedsUpdate() }} open var tooltipContent: String? { didSet { setNeedsUpdate() }}
open var tooltipContentView: UIView? { didSet { setNeedsUpdate() }}
open var transparentBackground: Bool = false { didSet { setNeedsUpdate() }} open var transparentBackground: Bool = false { didSet { setNeedsUpdate() }}
open var width: CGFloat? { didSet { setNeedsUpdate() }} open var width: CGFloat? { didSet { setNeedsUpdate() }}
@ -293,7 +295,7 @@ open class EntryField: Control, Changeable {
} }
if let tooltipTitle, let tooltipContent { 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 //set the titleLabel

View File

@ -16,7 +16,7 @@ extension TitleLockup {
public var numberOfLines: Int public var numberOfLines: Int
public init(text: String, public init(text: String,
isBold: Bool = false, isBold: Bool = true,
standardStyle: OtherStandardStyle = .bodyLarge, standardStyle: OtherStandardStyle = .bodyLarge,
textAttributes: [any LabelAttributeModel]? = nil, textAttributes: [any LabelAttributeModel]? = nil,
numberOfLines: Int = 0) { numberOfLines: Int = 0) {

View File

@ -50,9 +50,11 @@ open class Tooltip: Control, TooltipLaunchable {
open var size: Size = .medium { didSet { setNeedsUpdate() }} open var size: Size = .medium { didSet { setNeedsUpdate() }}
open var title: String = "" { didSet { setNeedsUpdate() }} open var title: String? { didSet { setNeedsUpdate() }}
open var content: String = "" { didSet { setNeedsUpdate() }} open var content: String? { didSet { setNeedsUpdate() }}
open var contentView: UIView? { didSet { setNeedsUpdate() }}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Configuration // MARK: - Configuration
@ -132,6 +134,7 @@ open class Tooltip: Control, TooltipLaunchable {
self.presentTooltip(surface: tooltip.surface, self.presentTooltip(surface: tooltip.surface,
title: tooltip.title, title: tooltip.title,
content: tooltip.content, content: tooltip.content,
contentView: tooltip.contentView,
closeButtonText: tooltip.closeButtonText) closeButtonText: tooltip.closeButtonText)
}) })
} }
@ -160,8 +163,13 @@ open class Tooltip: Control, TooltipLaunchable {
//get the color for the image //get the color for the image
let imageColor = iconColorConfiguration.getColor(self) let imageColor = iconColorConfiguration.getColor(self)
imageView.image = infoImage.withTintColor(imageColor) imageView.image = infoImage.withTintColor(imageColor)
var label = title
accessibilityLabel = "Tooltip: \(title)" if label == nil {
label = content
}
if let label {
accessibilityLabel = "Tooltip: \(label)"
}
} }
} }

View File

@ -10,7 +10,10 @@ import UIKit
import Combine import Combine
import VDSColorTokens 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>()
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Private Properties // MARK: - Private Properties
@ -26,15 +29,19 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
private var scrollView = UIScrollView().with { private var scrollView = UIScrollView().with {
$0.translatesAutoresizingMaskIntoConstraints = false $0.translatesAutoresizingMaskIntoConstraints = false
$0.backgroundColor = .clear $0.backgroundColor = .clear
$0.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -5)
} }
private let containerView = View().with { private let modalView = View().with {
$0.layer.cornerRadius = 8 $0.layer.cornerRadius = 8
$0.layer.shadowColor = UIColor.black.cgColor }
$0.layer.shadowOpacity = 0.5
$0.layer.shadowOffset = CGSize.zero public var contentView: UIView? = nil
$0.layer.shadowRadius = 5
private let contentStackView = UIStackView().with {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.axis = .vertical
$0.distribution = .fillProportionally
$0.spacing = 0
} }
private var line = Line().with { instance in private var line = Line().with { instance in
@ -45,15 +52,14 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
// MARK: - Public Properties // MARK: - Public Properties
//-------------------------------------------------- //--------------------------------------------------
open var surface: Surface = .light { didSet { updateView() }} 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 open var titleLabel = Label().with { label in
//use the same font/pointsize for both Title upsizes font in iPad label.textStyle = .boldTitleMedium
label.textStyle = UIDevice.isIPad ? .boldTitleSmall : .boldTitleMedium
} }
open var contentText: String = "" { didSet { updateView() }} open var contentText: String? { didSet { updateView() }}
open var contentLabel = Label().with { label in open var contentLabel = Label().with { label in
label.textStyle = .bodyMedium label.textStyle = .bodyLarge
} }
open var closeButtonText: String = "Close" { didSet { updateView() }} open var closeButtonText: String = "Close" { didSet { updateView() }}
@ -64,10 +70,6 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
button.setTitle("Close", for: .normal) button.setTitle("Close", for: .normal)
button.titleLabel?.font = TextStyle.bodyLarge.font button.titleLabel?.font = TextStyle.bodyLarge.font
button.translatesAutoresizingMaskIntoConstraints = false 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 return button
}() }()
@ -83,6 +85,10 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
private let closeButtonTextColorConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark) 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 // MARK: - Lifecycle
//-------------------------------------------------- //--------------------------------------------------
@ -93,71 +99,125 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
} }
open func setup() { open func setup() {
//left-right swipe
view.publisher(for: UISwipeGestureRecognizer().with{ $0.direction = .right })
.sink { [weak self] swipe in
guard let self else { return }
self.dismiss(animated: true, completion: nil)
}.store(in: &subscribers)
scrollView.addSubview(titleLabel) //tapping in background
scrollView.addSubview(contentLabel) view.publisher(for: UITapGestureRecognizer().with{ $0.numberOfTapsRequired = 1 })
containerView.addSubview(scrollView) .sink { [weak self] swipe in
containerView.addSubview(line) guard let self else { return }
containerView.addSubview(closeButton) self.dismiss(animated: true, completion: nil)
view.addSubview(containerView) }.store(in: &subscribers)
//clicking button
onClickSubscriber = closeButton.publisher(for: .touchUpInside)
.sink {[weak self] button in
guard let self else { return }
self.dismiss(animated: true, completion: nil)
}
contentStackView.addArrangedSubview(titleLabel)
contentStackView.addArrangedSubview(contentLabel)
scrollView.addSubview(contentStackView)
modalView.addSubview(scrollView)
modalView.addSubview(line)
modalView.addSubview(closeButton)
view.addSubview(modalView)
// Activate constraints
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
containerView.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: VDSLayout.Spacing.space8X.value), // Constraints for the floating modal view
containerView.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -VDSLayout.Spacing.space8X.value), modalView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
containerView.topAnchor.constraint(greaterThanOrEqualTo: view.topAnchor), modalView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
containerView.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor), modalView.widthAnchor.constraint(equalToConstant: 296),
modalView.heightAnchor.constraint(greaterThanOrEqualToConstant: 96),
modalView.heightAnchor.constraint(lessThanOrEqualToConstant: 312),
containerView.heightAnchor.constraint(equalToConstant: 312), // Constraints for the scroll view
containerView.widthAnchor.constraint(equalToConstant: 296), scrollView.topAnchor.constraint(equalTo: modalView.topAnchor, constant: VDSLayout.Spacing.space4X.value),
containerView.centerXAnchor.constraint(equalTo: view.centerXAnchor), scrollView.leadingAnchor.constraint(equalTo: modalView.leadingAnchor),
containerView.centerYAnchor.constraint(equalTo: view.centerYAnchor), scrollView.trailingAnchor.constraint(equalTo: modalView.trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo: line.topAnchor),
scrollView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: VDSLayout.Spacing.space4X.value), line.leadingAnchor.constraint(equalTo: modalView.leadingAnchor),
scrollView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: VDSLayout.Spacing.space4X.value), line.trailingAnchor.constraint(equalTo: modalView.trailingAnchor),
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.topAnchor.constraint(equalTo: line.bottomAnchor),
closeButton.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), closeButton.leadingAnchor.constraint(equalTo: modalView.leadingAnchor),
closeButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), closeButton.trailingAnchor.constraint(equalTo: modalView.trailingAnchor),
closeButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor), closeButton.bottomAnchor.constraint(equalTo: modalView.bottomAnchor),
closeButton.heightAnchor.constraint(equalToConstant: 44.0) closeButton.heightAnchor.constraint(equalToConstant: 44.0),
])
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))
])
} }
open func updateView() { open func updateView() {
view.backgroundColor = backgroundColorConfiguration.getColor(self).withAlphaComponent(0.3) view.backgroundColor = backgroundColorConfiguration.getColor(self).withAlphaComponent(0.3)
containerView.backgroundColor = containerViewBackgroundColorConfiguration.getColor(self) modalView.backgroundColor = containerViewBackgroundColorConfiguration.getColor(self)
scrollView.indicatorStyle = surface == .light ? .black : .white scrollView.indicatorStyle = surface == .light ? .black : .white
titleLabel.removeFromSuperview()
contentLabel.removeFromSuperview()
contentView?.removeFromSuperview()
titleLabel.surface = surface titleLabel.surface = surface
contentLabel.surface = surface contentLabel.surface = surface
line.surface = surface line.surface = surface
titleLabel.text = titleText titleLabel.text = titleText
contentLabel.text = contentText contentLabel.text = contentText
titleLabel.sizeToFit() titleLabel.sizeToFit()
contentLabel.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) let closeButtonTextColor = closeButtonTextColorConfiguration.getColor(self)
closeButton.setTitleColor(closeButtonTextColor, for: .normal) closeButton.setTitleColor(closeButtonTextColor, for: .normal)
closeButton.setTitleColor(closeButtonTextColor, for: .highlighted) closeButton.setTitleColor(closeButtonTextColor, for: .highlighted)
closeButton.setTitle(closeButtonText, for: .normal) closeButton.setTitle(closeButtonText, for: .normal)
scrollView.layoutIfNeeded()
} }
} }

View File

@ -9,16 +9,17 @@ import Foundation
import UIKit import UIKit
public protocol TooltipLaunchable { 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 { 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() { if let presenting = UIApplication.topViewController() {
let tooltipViewController = TooltipAlertViewController(nibName: nil, bundle: nil).with { let tooltipViewController = TooltipAlertViewController(nibName: nil, bundle: nil).with {
$0.surface = surface $0.surface = surface
$0.titleText = title $0.titleText = title
$0.contentText = content $0.contentText = content
$0.contentView = contentView
$0.closeButtonText = closeButtonText $0.closeButtonText = closeButtonText
$0.modalPresentationStyle = .overCurrentContext $0.modalPresentationStyle = .overCurrentContext
$0.modalTransitionStyle = .crossDissolve $0.modalTransitionStyle = .crossDissolve

View File

@ -36,9 +36,11 @@ open class TrailingTooltipLabel: View, TooltipLaunchable {
open var tooltipCloseButtonText: String = "Close" { didSet { setNeedsUpdate() } } 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 // MARK: - Overrides
@ -70,8 +72,8 @@ open class TrailingTooltipLabel: View, TooltipLaunchable {
label.disabled = disabled label.disabled = disabled
//add tooltip //add tooltip
if let labelText, !labelText.isEmpty, !tooltipTitle.isEmpty, !tooltipContent.isEmpty { if let labelText, !labelText.isEmpty {
label.addTooltip(model: .init(surface: surface, closeButtonText: tooltipCloseButtonText, title: tooltipTitle, content: tooltipContent)) label.addTooltip(model: .init(surface: surface, closeButtonText: tooltipCloseButtonText, title: tooltipTitle, content: tooltipContent, contentView: tooltipContentView))
} }
} }
@ -95,14 +97,15 @@ extension Label {
public struct TooltipModel { public struct TooltipModel {
public var surface: Surface public var surface: Surface
public var closeButtonText: String public var closeButtonText: String
public var title: String public var title: String?
public var content: String public var content: String?
public var contentView: UIView?
public init(surface: Surface = .light, closeButtonText: String = "Close", title: String, content: String) { public init(surface: Surface = .light, closeButtonText: String = "Close", title: String?, content: String?, contentView: UIView?) {
self.surface = surface self.surface = surface
self.closeButtonText = closeButtonText self.closeButtonText = closeButtonText
self.title = title self.title = title
self.content = content self.content = content
self.contentView = contentView
} }
} }
@ -121,7 +124,8 @@ extension Label {
let tooltip = TooltipLabelAttribute(surface: surface, let tooltip = TooltipLabelAttribute(surface: surface,
closeButtonText: model.closeButtonText, closeButtonText: model.closeButtonText,
title: model.title, title: model.title,
content: model.content) content: model.content,
contentView: model.contentView)
newAttributes.append(tooltip) newAttributes.append(tooltip)
} }

View File

@ -2,6 +2,11 @@
======= =======
- CXTDT-426626 - Toggle - Disabled "on" state - CXTDT-426626 - Toggle - Disabled "on" state
- CXTDT-427165 - Text Link Caret - Container should not have left/right padding - CXTDT-427165 - Text Link Caret - Container should not have left/right padding
- CXTDT-427358 - Tooltip - Body Copy incorrect style
- CXTDT-427328 - Title Lockup text style combinations do not match spec
- CXTDT-426527 - Tabs - Large Typography
- CXTDT-427362 - Tooltip - Should not be a drop shadow on modal
- CXTDT-427975 - Tooltip - Scrollbar, multiple
1.0.25 1.0.25
======= =======