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;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 25;
CURRENT_PROJECT_VERSION = 26;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
@ -1148,7 +1148,7 @@
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 25;
CURRENT_PROJECT_VERSION = 26;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;

View File

@ -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)
}
}

View File

@ -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

View File

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

View File

@ -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)"
}
}
}

View File

@ -10,8 +10,11 @@ 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>()
//--------------------------------------------------
// MARK: - Private Properties
//--------------------------------------------------
@ -26,15 +29,19 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
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 {
private let modalView = 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
}
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
@ -45,15 +52,14 @@ 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
//use the same font/pointsize for both Title upsizes font in iPad
label.textStyle = UIDevice.isIPad ? .boldTitleSmall : .boldTitleMedium
label.textStyle = .boldTitleMedium
}
open var contentText: String = "" { didSet { updateView() }}
open var contentText: String? { didSet { updateView() }}
open var contentLabel = Label().with { label in
label.textStyle = .bodyMedium
label.textStyle = .bodyLarge
}
open var closeButtonText: String = "Close" { didSet { updateView() }}
@ -64,10 +70,6 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
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
}()
@ -83,6 +85,10 @@ 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
//--------------------------------------------------
@ -93,71 +99,125 @@ open class TooltipAlertViewController: UIViewController, Surfaceable {
}
open func setup() {
scrollView.addSubview(titleLabel)
scrollView.addSubview(contentLabel)
containerView.addSubview(scrollView)
containerView.addSubview(line)
containerView.addSubview(closeButton)
view.addSubview(containerView)
//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)
//tapping in background
view.publisher(for: UITapGestureRecognizer().with{ $0.numberOfTapsRequired = 1 })
.sink { [weak self] swipe in
guard let self else { return }
self.dismiss(animated: true, completion: nil)
}.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([
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),
// Constraints for the floating modal view
modalView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
modalView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
modalView.widthAnchor.constraint(equalToConstant: 296),
modalView.heightAnchor.constraint(greaterThanOrEqualToConstant: 96),
modalView.heightAnchor.constraint(lessThanOrEqualToConstant: 312),
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),
// Constraints for the scroll view
scrollView.topAnchor.constraint(equalTo: modalView.topAnchor, constant: VDSLayout.Spacing.space4X.value),
scrollView.leadingAnchor.constraint(equalTo: modalView.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: modalView.trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo: line.topAnchor),
line.leadingAnchor.constraint(equalTo: modalView.leadingAnchor),
line.trailingAnchor.constraint(equalTo: modalView.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)
closeButton.leadingAnchor.constraint(equalTo: modalView.leadingAnchor),
closeButton.trailingAnchor.constraint(equalTo: modalView.trailingAnchor),
closeButton.bottomAnchor.constraint(equalTo: modalView.bottomAnchor),
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() {
view.backgroundColor = backgroundColorConfiguration.getColor(self).withAlphaComponent(0.3)
containerView.backgroundColor = containerViewBackgroundColorConfiguration.getColor(self)
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()
}
}

View File

@ -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

View File

@ -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)
}

View File

@ -2,6 +2,11 @@
=======
- CXTDT-426626 - Toggle - Disabled "on" state
- 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
=======