refactored for breadcrumbs wordwrap
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
756aa17e5d
commit
66a386a300
@ -13,78 +13,14 @@ final class BreadcrumbCellItem: UICollectionViewCell {
|
||||
|
||||
///Identifier for the BreadcrumbCellItem
|
||||
static let identifier: String = String(describing: BreadcrumbCellItem.self)
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Properties
|
||||
//--------------------------------------------------
|
||||
internal var stackView: UIStackView = {
|
||||
return UIStackView().with {
|
||||
$0.translatesAutoresizingMaskIntoConstraints = false
|
||||
$0.axis = .horizontal
|
||||
$0.distribution = .fill
|
||||
$0.alignment = .fill
|
||||
$0.spacing = VDSLayout.space1X
|
||||
$0.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
|
||||
$0.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
||||
}
|
||||
}()
|
||||
|
||||
internal var breadCrumbItem: BreadcrumbItem?
|
||||
|
||||
///separator label
|
||||
private var separator: Label = Label().with {
|
||||
$0.translatesAutoresizingMaskIntoConstraints = false
|
||||
$0.textAlignment = .left
|
||||
$0.numberOfLines = 1
|
||||
$0.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
|
||||
$0.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
||||
$0.text = "/"
|
||||
}
|
||||
|
||||
private let textColorConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark)
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setUp()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
setUp()
|
||||
}
|
||||
|
||||
///Configuring the cell with default setup
|
||||
private func setUp() {
|
||||
separator.textColorConfiguration = textColorConfiguration.eraseToAnyColorable()
|
||||
contentView.addSubview(stackView)
|
||||
stackView.pinToSuperView()
|
||||
separator.backgroundColor = .clear
|
||||
}
|
||||
|
||||
|
||||
///Updating the breadCrumbItem and UI based on the selected flag along with the surface
|
||||
func update(surface: Surface, hideSlash: Bool, breadCrumbItem: BreadcrumbItem) {
|
||||
//update surface
|
||||
separator.surface = surface
|
||||
breadCrumbItem.surface = surface
|
||||
func update(breadCrumbItem: BreadcrumbItem) {
|
||||
contentView.subviews.forEach{$0.removeFromSuperview()}
|
||||
contentView.addSubview(breadCrumbItem)
|
||||
breadCrumbItem.pinToSuperView()
|
||||
breadCrumbItem.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
||||
breadCrumbItem.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
||||
|
||||
//remove previous views
|
||||
stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
|
||||
|
||||
//add to stack
|
||||
stackView.addArrangedSubview(separator)
|
||||
stackView.addArrangedSubview(breadCrumbItem)
|
||||
stackView.setCustomSpacing(VDSLayout.space1X, after: separator)
|
||||
|
||||
//update separator
|
||||
separator.textColor = textColorConfiguration.getColor(surface)
|
||||
separator.isHidden = hideSlash
|
||||
self.breadCrumbItem = breadCrumbItem
|
||||
setNeedsLayout()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -42,17 +42,23 @@ open class BreadcrumbItem: ButtonBase {
|
||||
textColorConfiguration.getColor(self)
|
||||
}
|
||||
|
||||
/// The natural size for the receiving view, considering only properties of the view itself.
|
||||
open override var intrinsicContentSize: CGSize {
|
||||
guard let titleLabel else { return super.intrinsicContentSize }
|
||||
// Calculate the titleLabel's intrinsic content size
|
||||
let labelSize = titleLabel.sizeThatFits(CGSize(width: self.frame.width, height: CGFloat.greatestFiniteMagnitude))
|
||||
// Adjust the size if needed (add any additional padding if your design requires)
|
||||
let adjustedSize = CGSize(width: labelSize.width + contentEdgeInsets.left + contentEdgeInsets.right,
|
||||
height: labelSize.height + contentEdgeInsets.top + contentEdgeInsets.bottom)
|
||||
return adjustedSize
|
||||
/// Determines if a slash is predended or not.
|
||||
open var hideSlash: Bool = false { didSet { setNeedsUpdate() } }
|
||||
|
||||
private var slashText = "/ "
|
||||
|
||||
open override var textAttributes: [any LabelAttributeModel]? {
|
||||
hideSlash
|
||||
? nil
|
||||
: [ColorLabelAttribute(location: 0,
|
||||
length: 1,
|
||||
color: surface == .light ? VDSColor.elementsPrimaryOnlight : VDSColor.elementsPrimaryOndark),
|
||||
TextStyleLabelAttribute(location: 0,
|
||||
length: 1,
|
||||
textStyle: .bodySmall)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Properties
|
||||
//--------------------------------------------------
|
||||
@ -68,15 +74,51 @@ open class BreadcrumbItem: ButtonBase {
|
||||
/// 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()
|
||||
|
||||
titleLabel?.numberOfLines = 0
|
||||
titleLabel?.lineBreakMode = .byWordWrapping
|
||||
contentHorizontalAlignment = .left
|
||||
|
||||
isAccessibilityElement = true
|
||||
accessibilityTraits = .link
|
||||
contentHorizontalAlignment = .leading
|
||||
|
||||
}
|
||||
|
||||
/// Used to make changes to the View based off a change events or from local properties.
|
||||
open override func updateView() {
|
||||
//always call last so the label is rendered
|
||||
super.updateView()
|
||||
|
||||
//clear the arrays holding actions
|
||||
accessibilityCustomActions = []
|
||||
if let text, !text.isEmpty {
|
||||
var updatedText = text
|
||||
if updatedText.hasPrefix(slashText) && hideSlash {
|
||||
updatedText = String(updatedText.dropFirst(slashText.count))
|
||||
} else if !hideSlash, !updatedText.hasPrefix(slashText) {
|
||||
updatedText = slashText + updatedText
|
||||
}
|
||||
|
||||
//create the primary string
|
||||
let mutableText = NSMutableAttributedString.mutableText(for: updatedText,
|
||||
textStyle: textStyle,
|
||||
useScaledFont: useScaledFont,
|
||||
textColor: textColor,
|
||||
alignment: titleLabel?.textAlignment ?? .center,
|
||||
lineBreakMode: titleLabel?.lineBreakMode ?? .byTruncatingTail)
|
||||
|
||||
//apply any attributes
|
||||
if let attributes = textAttributes {
|
||||
mutableText.apply(attributes: attributes)
|
||||
}
|
||||
|
||||
//set the attributed text
|
||||
setAttributedTitle(mutableText, for: .normal)
|
||||
setAttributedTitle(mutableText, for: .highlighted)
|
||||
invalidateIntrinsicContentSize()
|
||||
} else {
|
||||
setAttributedTitle(nil, for: .normal)
|
||||
setAttributedTitle(nil, for: .highlighted)
|
||||
titleLabel?.text = nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -32,13 +32,6 @@ open class Breadcrumbs: View {
|
||||
}
|
||||
}
|
||||
|
||||
/// Current Surface and this is used to pass down to child objects that implement Surfacable
|
||||
override open var surface: Surface {
|
||||
didSet {
|
||||
breadcrumbs.forEach { $0.surface = surface }
|
||||
}
|
||||
}
|
||||
|
||||
open override var accessibilityElements: [Any]? {
|
||||
get {
|
||||
return [containerView, breadcrumbs]
|
||||
@ -165,17 +158,22 @@ extension Breadcrumbs: UICollectionViewDelegate, UICollectionViewDataSource, But
|
||||
|
||||
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BreadcrumbCellItem.identifier, for: indexPath) as? BreadcrumbCellItem else { return UICollectionViewCell() }
|
||||
let hideSlash = indexPath.row == 0
|
||||
cell.update(surface: surface, hideSlash: hideSlash, breadCrumbItem: breadcrumbs[indexPath.row])
|
||||
let breadcrumb = breadcrumbs[indexPath.row]
|
||||
breadcrumb.hideSlash = breadcrumb == breadcrumbs.first
|
||||
breadcrumb.surface = surface
|
||||
cell.update(breadCrumbItem: breadcrumb)
|
||||
return cell
|
||||
}
|
||||
|
||||
public func collectionView(_ collectionView: UICollectionView, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
|
||||
|
||||
let breadcrumb = breadcrumbs[indexPath.row]
|
||||
let intrinsicSize = breadcrumb.intrinsicContentSize
|
||||
let separatorFullWidth: CGFloat = indexPath.row == 0 ? 0 : VDSLayout.space1X + separatorWidth
|
||||
let cellwidth = intrinsicSize.width + separatorFullWidth
|
||||
return .init(width: min(cellwidth, collectionView.frame.width), height: intrinsicSize.height)
|
||||
breadcrumb.hideSlash = breadcrumb == breadcrumbs.first
|
||||
|
||||
let maxWidth = frame.width
|
||||
let intrinsicSize = breadcrumb.titleLabel!.sizeThatFits(.init(width: maxWidth, height: CGFloat.greatestFiniteMagnitude))
|
||||
let cellwidth = min(maxWidth, intrinsicSize.width)
|
||||
return .init(width: cellwidth, height: intrinsicSize.height)
|
||||
}
|
||||
|
||||
public func collectionView(_ collectionView: UICollectionView, buttonBaseAtIndexPath indexPath: IndexPath) -> ButtonBase {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user