diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index ef6acb80..5d78557f 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 44604AD729CE196600E62B51 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD629CE196600E62B51 /* Line.swift */; }; 5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */; }; 5FC35BE328D51405004EBEAC /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC35BE228D51405004EBEAC /* Button.swift */; }; + 710607952B91A99500F2863F /* TitleletChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 710607942B91A99500F2863F /* TitleletChangeLog.txt */; }; 7115BD3C2B84C0C200E0A610 /* TileContainerChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 7115BD3B2B84C0C200E0A610 /* TileContainerChangeLog.txt */; }; 71BFA70A2B7F70E6000DCE33 /* Dropshadowable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71BFA7092B7F70E6000DCE33 /* Dropshadowable.swift */; }; 71C02B382B7BD98F00E93E66 /* NotificationChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 71C02B372B7BD98F00E93E66 /* NotificationChangeLog.txt */; }; @@ -180,6 +181,7 @@ 44604AD629CE196600E62B51 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Useable.swift; sourceTree = ""; }; 5FC35BE228D51405004EBEAC /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = ""; }; + 710607942B91A99500F2863F /* TitleletChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = TitleletChangeLog.txt; sourceTree = ""; }; 7115BD3B2B84C0C200E0A610 /* TileContainerChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = TileContainerChangeLog.txt; sourceTree = ""; }; 71BFA7092B7F70E6000DCE33 /* Dropshadowable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dropshadowable.swift; sourceTree = ""; }; 71C02B372B7BD98F00E93E66 /* NotificationChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = NotificationChangeLog.txt; sourceTree = ""; }; @@ -676,6 +678,7 @@ EA985BE929689B6D00F2FF2E /* TileletSubTitleModel.swift */, EA985BE72968951C00F2FF2E /* TileletTitleModel.swift */, EA985C2C296F03FE00F2FF2E /* TileletIconModels.swift */, + 710607942B91A99500F2863F /* TitleletChangeLog.txt */, ); path = Tilelet; sourceTree = ""; @@ -947,6 +950,7 @@ 71C02B382B7BD98F00E93E66 /* NotificationChangeLog.txt in Resources */, EAEEECA72B1F952000531FC2 /* TabsChangeLog.txt in Resources */, EAEEEC962B1F893B00531FC2 /* ButtonChangeLog.txt in Resources */, + 710607952B91A99500F2863F /* TitleletChangeLog.txt in Resources */, EA5F86CC2A1D28B500BC83E4 /* ReleaseNotes.txt in Resources */, EAEEEC982B1F8DD100531FC2 /* LineChangeLog.txt in Resources */, EAEEECA22B1F92AD00531FC2 /* LabelChangeLog.txt in Resources */, diff --git a/VDS/Components/Badge/Badge.swift b/VDS/Components/Badge/Badge.swift index f6bb36d5..bbe1233d 100644 --- a/VDS/Components/Badge/Badge.swift +++ b/VDS/Components/Badge/Badge.swift @@ -147,6 +147,7 @@ open class Badge: View { label.widthGreaterThanEqualTo(constant: minWidth) maxWidthConstraint = label.widthLessThanEqualTo(constant: 0).with { $0.isActive = false } + clipsToBounds = true } /// Resets to default settings. diff --git a/VDS/Components/Tilelet/Tilelet.swift b/VDS/Components/Tilelet/Tilelet.swift index 657a735b..e562ff0a 100644 --- a/VDS/Components/Tilelet/Tilelet.swift +++ b/VDS/Components/Tilelet/Tilelet.swift @@ -39,6 +39,7 @@ open class Tilelet: TileContainer { /// Enum to represent the Vertical Layout of the Text. public enum TextPosition: String, CaseIterable { case top + case middle case bottom } @@ -72,7 +73,7 @@ open class Tilelet: TileContainer { //-------------------------------------------------- // MARK: - Public Properties - //-------------------------------------------------- + //-------------------------------------------------- public override var onClickSubscriber: AnyCancellable? { didSet { isAccessibilityElement = onClickSubscriber != nil @@ -82,6 +83,27 @@ open class Tilelet: TileContainer { /// Title lockup positioned in the contentView. open var titleLockup = TitleLockup().with { $0.standardStyleConfiguration = .init(styleConfigurations: [ + .init(deviceType: .iPhone, + titleStandardStyles: [.bodySmall], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodySmall], + topSpacing: VDSLayout.Spacing.space1X.value, + bottomSpacing: VDSLayout.Spacing.space1X.value) + ]), + .init(deviceType: .iPhone, + titleStandardStyles: [.bodyMedium], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyMedium], + topSpacing: VDSLayout.Spacing.space1X.value, + bottomSpacing: VDSLayout.Spacing.space1X.value) + ]), + .init(deviceType: .iPhone, + titleStandardStyles: [.bodyLarge], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyLarge], + topSpacing: VDSLayout.Spacing.space1X.value, + bottomSpacing: VDSLayout.Spacing.space1X.value) + ]), .init(deviceType: .iPhone, titleStandardStyles: [.titleSmall], spacingConfigurations: [ @@ -103,6 +125,27 @@ open class Tilelet: TileContainer { topSpacing: VDSLayout.Spacing.space3X.value, bottomSpacing: VDSLayout.Spacing.space3X.value) ]), + .init(deviceType: .iPad, + titleStandardStyles: [.bodySmall], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodySmall], + topSpacing: VDSLayout.Spacing.space2X.value, + bottomSpacing: VDSLayout.Spacing.space2X.value) + ]), + .init(deviceType: .iPad, + titleStandardStyles: [.bodyMedium], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyMedium], + topSpacing: VDSLayout.Spacing.space1X.value, + bottomSpacing: VDSLayout.Spacing.space1X.value) + ]), + .init(deviceType: .iPad, + titleStandardStyles: [.bodyLarge], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyLarge], + topSpacing: VDSLayout.Spacing.space1X.value, + bottomSpacing: VDSLayout.Spacing.space1X.value) + ]), .init(deviceType: .iPad, titleStandardStyles: [.titleSmall, .titleMedium], spacingConfigurations: [ @@ -206,6 +249,12 @@ open class Tilelet: TileContainer { //-------------------------------------------------- internal var titleLockupWidthConstraint: NSLayoutConstraint? internal var titleLockupTrailingConstraint: NSLayoutConstraint? + internal var titleLockupTopConstraint: NSLayoutConstraint? + internal var titleLockupBottomConstraint: NSLayoutConstraint? + internal var titleLockupTopGreaterThanConstraint: NSLayoutConstraint? + internal var titleLockupBottomGreaterThanConstraint: NSLayoutConstraint? + internal var titleLockupCenterYConstraint: NSLayoutConstraint? + internal var titleLockupTitleLabelBottomConstraint: NSLayoutConstraint? //-------------------------------------------------- // MARK: - Overrides @@ -230,11 +279,16 @@ open class Tilelet: TileContainer { titleLockupContainerView.addSubview(titleLockup) titleLockup - .pinTop() .pinLeading() - .pinBottom() + titleLockupTopConstraint = titleLockup.topAnchor.constraint(equalTo: titleLockupContainerView.topAnchor) + titleLockupTopConstraint?.activate() + titleLockupBottomConstraint = titleLockupContainerView.bottomAnchor.constraint(equalTo: titleLockup.bottomAnchor) + titleLockupBottomConstraint?.activate() titleLockupTrailingConstraint = titleLockup.trailingAnchor.constraint(equalTo: titleLockupContainerView.trailingAnchor) titleLockupTrailingConstraint?.isActive = true + titleLockupBottomGreaterThanConstraint = titleLockupContainerView.bottomAnchor.constraint(greaterThanOrEqualTo: titleLockup.bottomAnchor) + titleLockupTopGreaterThanConstraint = titleLockup.topAnchor.constraint(greaterThanOrEqualTo: titleLockupContainerView.topAnchor) + titleLockupCenterYConstraint = titleLockup.centerYAnchor.constraint(equalTo: titleLockupContainerView.centerYAnchor) iconContainerView.addSubview(descriptiveIcon) iconContainerView.addSubview(directionalIcon) @@ -249,6 +303,12 @@ open class Tilelet: TileContainer { .pinTop() .pinBottom() + padding = .custom( UIDevice.isIPad ? VDSLayout.Spacing.space6X.value : VDSLayout.Spacing.space4X.value) + //If a Tilelet has Badge, Title and Subtitle, then Subtitle will be truncated first and Badge will be truncated second. Title will be truncated last (lowest priority). + var labelPriority = UILayoutPriority.defaultHigh.rawValue + titleLockup.titleLabel.setContentCompressionResistancePriority(UILayoutPriority(labelPriority), for: .vertical) + badge.label.setContentCompressionResistancePriority(UILayoutPriority(labelPriority-1), for: .vertical) + titleLockup.subTitleLabel.setContentCompressionResistancePriority(UILayoutPriority(labelPriority-2), for: .vertical) } /// Resets to default settings. @@ -261,7 +321,7 @@ open class Tilelet: TileContainer { titleModel = nil subTitleModel = nil descriptiveIconModel = nil - directionalIconModel = nil + directionalIconModel = nil shouldUpdateView = true setNeedsUpdate() } @@ -273,7 +333,11 @@ open class Tilelet: TileContainer { updateBadge() updateTitleLockup() updateIcons() - + ///Content-driven height Tilelets - Minimum height is configurable. + ///if width != nil && (aspectRatio != .none || height != nil) then tilelet is not self growing, so we can apply text position alignments. + if width != nil && (aspectRatio != .none || height != nil) { + updateTextPositionAlignment() + } layoutIfNeeded() } @@ -401,20 +465,59 @@ open class Tilelet: TileContainer { } else { removeFromSuperview(iconContainerView) } + if let lastElement = titleLockup.lastElement { + titleLockupTitleLabelBottomConstraint?.deactivate() + let anchorConstraint = showIconContainerView ? iconContainerView.topAnchor : containerView.bottomAnchor + titleLockupTitleLabelBottomConstraint = anchorConstraint.constraint(greaterThanOrEqualTo: lastElement.bottomAnchor) + titleLockupTitleLabelBottomConstraint?.activate() + } + } + + private func updateTextPositionAlignment() { + switch textPostion { + case .top: + titleLockupTopConstraint?.activate() + titleLockupTopGreaterThanConstraint?.deactivate() + titleLockupBottomConstraint?.deactivate() + titleLockupBottomGreaterThanConstraint?.activate() + titleLockupCenterYConstraint?.deactivate() + case .middle: + titleLockupTopConstraint?.deactivate() + titleLockupTopGreaterThanConstraint?.activate() + titleLockupBottomConstraint?.deactivate() + titleLockupBottomGreaterThanConstraint?.activate() + titleLockupCenterYConstraint?.activate() + case .bottom: + titleLockupTopConstraint?.deactivate() + titleLockupTopGreaterThanConstraint?.activate() + titleLockupBottomConstraint?.activate() + titleLockupBottomGreaterThanConstraint?.deactivate() + titleLockupCenterYConstraint?.deactivate() + } + } +} + +extension TitleLockup { + + fileprivate var lastElement: UIView? { + guard subTitleModel == nil else { return subTitleLabel } + guard titleModel == nil else { return titleLabel } + return nil } } extension TileContainer.Padding { + fileprivate var tiletSpacing: CGFloat { switch self { - case .padding2X: - return 16 case .padding4X: return 24 case .padding6X: return 32 - case .padding8X: - return 48 + case .custom(let padding): + if padding == VDSLayout.Spacing.space3X.value { + return 16 + } else { fallthrough } default: return 16 } diff --git a/VDS/Components/Tilelet/TileletBadgeModel.swift b/VDS/Components/Tilelet/TileletBadgeModel.swift index f58c134c..9dbd03fe 100644 --- a/VDS/Components/Tilelet/TileletBadgeModel.swift +++ b/VDS/Components/Tilelet/TileletBadgeModel.swift @@ -6,6 +6,7 @@ // import Foundation +import UIKit extension Tilelet { @@ -26,12 +27,16 @@ extension Tilelet { /// Max width that will be used for the badge. public var maxWidth: CGFloat? - public init(text: String, fillColor: Badge.FillColor = .red, surface: Surface = .light, numberOfLines: Int = 0, maxWidth: CGFloat? = nil) { + /// LineBreakMode used in Badge label. + public var lineBreakMode: NSLineBreakMode + + public init(text: String, fillColor: Badge.FillColor = .red, surface: Surface = .light, numberOfLines: Int = 0, maxWidth: CGFloat? = nil, lineBreakMode: NSLineBreakMode = .byTruncatingTail) { self.text = text self.fillColor = fillColor self.surface = surface self.numberOfLines = numberOfLines self.maxWidth = maxWidth + self.lineBreakMode = lineBreakMode } } } diff --git a/VDS/Components/Tilelet/TileletSubTitleModel.swift b/VDS/Components/Tilelet/TileletSubTitleModel.swift index dab4c81c..63820316 100644 --- a/VDS/Components/Tilelet/TileletSubTitleModel.swift +++ b/VDS/Components/Tilelet/TileletSubTitleModel.swift @@ -6,6 +6,7 @@ // import Foundation +import UIKit extension Tilelet { /// Model that represents the options available for the sub title label. @@ -18,7 +19,8 @@ extension Tilelet { case bodyLarge case bodyMedium case bodySmall - + case titleSmall + case titleMedium public var defaultValue: TitleLockup.OtherStandardStyle { .bodySmall } } //-------------------------------------------------- @@ -36,17 +38,22 @@ extension Tilelet { /// Text color that will be used for the subTitle label. public var textColor: Use = .primary + /// LineBreakMode used in Badge label. + public var lineBreakMode: NSLineBreakMode + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- public init(text: String, textColor: Use = .primary, textAttributes: [any LabelAttributeModel]? = nil, - standardStyle: StandardStyle = .bodySmall) { + standardStyle: StandardStyle = .bodySmall, + lineBreakMode: NSLineBreakMode = .byTruncatingTail) { self.text = text self.textAttributes = textAttributes self.textColor = textColor self.standardStyle = standardStyle + self.lineBreakMode = lineBreakMode } //-------------------------------------------------- @@ -57,7 +64,7 @@ extension Tilelet { TitleLockup.SubTitleModel(text: text, standardStyle: standardStyle.value, textColor: textColor, - textAttributes: textAttributes) + textAttributes: textAttributes, lineBreakMode: lineBreakMode) } } } diff --git a/VDS/Components/Tilelet/TileletTitleModel.swift b/VDS/Components/Tilelet/TileletTitleModel.swift index 728de07b..fa8c603d 100644 --- a/VDS/Components/Tilelet/TileletTitleModel.swift +++ b/VDS/Components/Tilelet/TileletTitleModel.swift @@ -6,6 +6,7 @@ // import Foundation +import UIKit extension Tilelet { /// Model that represents the options available for the title label. @@ -19,7 +20,10 @@ extension Tilelet { case titleLarge case titleMedium case titleSmall - + case bodyLarge + case bodyMedium + case bodySmall + public var defaultValue: TitleLockup.TitleStandardStyle { .titleSmall } } //-------------------------------------------------- @@ -28,21 +32,30 @@ extension Tilelet { /// Text that will be used for the title label. public var text: String = "" + /// Used in combination with standardStyle to set the textStyle that will be used for the title label. + public var isBold: Bool = false /// Text attributes that will be used for the title label. public var textAttributes: [any LabelAttributeModel]? /// Text style that will be used for the title label. public var standardStyle: StandardStyle = .titleSmall + /// LineBreakMode used in Badge label. + public var lineBreakMode: NSLineBreakMode + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- public init(text: String, textAttributes: [any LabelAttributeModel]? = nil, - standardStyle: StandardStyle = .titleSmall) { + isBold: Bool = true, + standardStyle: StandardStyle = .titleSmall, + lineBreakMode: NSLineBreakMode = .byTruncatingTail) { self.text = text self.textAttributes = textAttributes self.standardStyle = standardStyle + self.isBold = isBold + self.lineBreakMode = lineBreakMode } //-------------------------------------------------- @@ -52,7 +65,7 @@ extension Tilelet { public func toTitleLockupTitleModel() -> TitleLockup.TitleModel { TitleLockup.TitleModel(text: text, textAttributes: textAttributes, - standardStyle: standardStyle.value) + isBold: isBold, standardStyle: standardStyle.value, lineBreakMode: lineBreakMode) } } } diff --git a/VDS/Components/Tilelet/TitleletChangeLog.txt b/VDS/Components/Tilelet/TitleletChangeLog.txt new file mode 100644 index 00000000..bbbc8edf --- /dev/null +++ b/VDS/Components/Tilelet/TitleletChangeLog.txt @@ -0,0 +1,110 @@ +MM/DD/YYYY +---------------- + +08/31/2022 +---------------- +- Updates to Typography and default Title Lockup configurations: +- Default +- Regular title updated to bold weight +- Subtitle updated to primary color +- Inverted +- Regular title updated to bold weight +- Subtitle updated to primary color + +07/15/2022 +---------------- +- Updates to Typography and default Title Lockup configurations: +- Default +- Bold Title updated to Regular weight +- Subtitle updated to secondary color +- Inverted +- Bold Title updated to Regular weight +- Subtitle updated to secondary color + +04/27/2022 +---------------- +- Updates to Title Lockup configurations. + +04/14/2022 +---------------- +- Updates to Tilelet Group spec based on 4/14 handoff feedback. + +04/04/2022 +---------------- +- Visuals added to Tilelet Group spec. + +04/01/2022 +---------------- +- Updates based on 3/31 handoff feedback. + +03/30/2022 +---------------- +- Tilelet added to Test App. + +03/29/2022 +---------------- +- Interactive states updated. + +03/22/2022 +---------------- +- Layout and spacing page added. + +03/21/2022 +---------------- +- Updated anatomy, configuration, and element pages. + +02/21/2022 +---------------- +- Title Lockup’s width properties added. + +09/14/2022 +---------------- +- States section updated to reflect states inherited from Tile Container +- Dev note added to Layouts. + +11/30/2022 +---------------- +- Added "(web only)" to any instance of "keyboard focus" + +12/13/2022 +---------------- +- Replaced focus border pixel and style & spacing values with tokens. + +06/19/2023 +---------------- +- Updated anatomy element names to be local to Tilelet and indicated the core component that powers them under the hood. + +09/21/2023 +---------------- +- Updated Anatomy to include Title Lockup with Eyebrow and Tooltip +- Updated Configurations to include Title Lockup section +- Updated Layout and spacing to include Alignment (Left, Center) and textPosition (Middle)
 +- Updated Elements to include Eyebrow and uniform 1:1 pairings + +10/09/2023 +---------------- +- Updated Configurations VDS Title Lockup and VDS Tile Container sections. + +10/13/2023 +---------------- +- SPEC format changes to Anatomy to include nested component configurations +- Removed Configurations page + +11/20/2023 +---------------- +- Updated visuals to reflect new corner radius value - 12px +- Updated focus border corner radius to 14px +- View changes + +12/14/2023 +---------------- +- Added secondary, primary backgroundColor options +- Relabeled configurations section headings to use property names +- Relabeled surface sections to use “surface:” labeling convention +- Deprecated gray backgroundColor +- View changes + +02/08/2024 +---------------- +- Added external-icon option to Descriptive Icon in Configurations +- View changes diff --git a/VDS/Components/TitleLockup/TitleLockup.swift b/VDS/Components/TitleLockup/TitleLockup.swift index dbfd8637..6dc42e70 100644 --- a/VDS/Components/TitleLockup/TitleLockup.swift +++ b/VDS/Components/TitleLockup/TitleLockup.swift @@ -350,7 +350,7 @@ open class TitleLockup: View { titleLabel.attributes = titleModel.textAttributes titleLabel.numberOfLines = titleModel.numberOfLines titleLabel.surface = surface - + titleLabel.lineBreakMode = titleModel.lineBreakMode addSubview(titleLabel) titleLabel .pinTop(previousView?.bottomAnchor ?? self.topAnchor, eyebrowLabel == previousView ? topSpacing : 0) @@ -369,7 +369,7 @@ open class TitleLockup: View { subTitleLabel.attributes = subTitleModel.textAttributes subTitleLabel.numberOfLines = subTitleModel.numberOfLines subTitleLabel.surface = surface - + subTitleLabel.lineBreakMode = subTitleModel.lineBreakMode addSubview(subTitleLabel) subTitleLabel .pinTop(previousView?.bottomAnchor ?? self.topAnchor, (eyebrowLabel == previousView || titleLabel == previousView) ? bottomSpacing : 0) diff --git a/VDS/Components/TitleLockup/TitleLockupSubTitleModel.swift b/VDS/Components/TitleLockup/TitleLockupSubTitleModel.swift index 3ba6c7ff..5ad105ef 100644 --- a/VDS/Components/TitleLockup/TitleLockupSubTitleModel.swift +++ b/VDS/Components/TitleLockup/TitleLockupSubTitleModel.swift @@ -6,6 +6,7 @@ // import Foundation +import UIKit extension TitleLockup { /// Model that represents the options available for the sub title label. @@ -25,16 +26,21 @@ extension TitleLockup { /// Number of lines used in the subtitle label. public var numberOfLines: Int + /// LineBreakMode used in subtitle label. + public var lineBreakMode: NSLineBreakMode + public init(text: String, standardStyle: OtherStandardStyle = .bodyLarge, textColor: Use = .primary, textAttributes: [any LabelAttributeModel]? = nil, - numberOfLines: Int = 0) { + numberOfLines: Int = 0, + lineBreakMode: NSLineBreakMode = .byWordWrapping) { self.text = text self.standardStyle = standardStyle self.textColor = textColor self.textAttributes = textAttributes self.numberOfLines = numberOfLines + self.lineBreakMode = lineBreakMode } /// TextStyle used to render the text. diff --git a/VDS/Components/TitleLockup/TitleLockupTitleModel.swift b/VDS/Components/TitleLockup/TitleLockupTitleModel.swift index 2b957276..7541151f 100644 --- a/VDS/Components/TitleLockup/TitleLockupTitleModel.swift +++ b/VDS/Components/TitleLockup/TitleLockupTitleModel.swift @@ -6,6 +6,7 @@ // import Foundation +import UIKit extension TitleLockup { /// Model that represents the options available for the sub title label. @@ -25,16 +26,21 @@ extension TitleLockup { /// Number of lines that will be used for the title label. public var numberOfLines: Int + /// LineBreakMode used in subtitle label. + public var lineBreakMode: NSLineBreakMode + public init(text: String, textAttributes: [any LabelAttributeModel]? = nil, isBold: Bool = true, standardStyle: TitleStandardStyle = .featureXSmall, - numberOfLines: Int = 0) { + numberOfLines: Int = 0, + lineBreakMode: NSLineBreakMode = .byTruncatingTail) { self.text = text self.isBold = isBold self.textAttributes = textAttributes self.standardStyle = standardStyle self.numberOfLines = numberOfLines + self.lineBreakMode = lineBreakMode } /// TextStyle used to render the text.