Merge branch 'refactor/label' into 'release/11_4_0'

updated to fix issue for attributedText

See merge request BPHV_MIPS/vds_ios!171
This commit is contained in:
Bruce, Matt R 2024-03-08 20:33:07 +00:00
commit c45270d94c
8 changed files with 132 additions and 47 deletions

View File

@ -102,7 +102,6 @@ open class SelectorItemBase<Selector: SelectorControlable>: Control, Errorable,
/// Instead of use labelText and labelTextAttirbutes, this is a fully baked NSAttributedString with both text and attributes.
open var labelAttributedText: NSAttributedString? {
didSet {
label.useAttributedText = !(labelAttributedText?.string.isEmpty ?? true)
label.attributedText = labelAttributedText
setNeedsUpdate()
}
@ -117,7 +116,6 @@ open class SelectorItemBase<Selector: SelectorControlable>: Control, Errorable,
/// Instead of use childText and childTextAttirbutes, this is a fully baked NSAttributedString with both text and attributes.
open var childAttributedText: NSAttributedString? {
didSet {
childLabel.useAttributedText = !(childAttributedText?.string.isEmpty ?? true)
childLabel.attributedText = childAttributedText
setNeedsUpdate()
}

View File

@ -102,6 +102,7 @@ open class ButtonBase: UIButton, ViewProtocol, UserInfoable, Clickable {
//--------------------------------------------------
open func initialSetup() {
if !initialSetupPerformed {
initialSetupPerformed = true
backgroundColor = .clear
translatesAutoresizingMaskIntoConstraints = false
accessibilityCustomActions = []

View File

@ -42,6 +42,13 @@ open class Label: UILabel, ViewProtocol, UserInfoable {
//--------------------------------------------------
// MARK: - Private Properties
//--------------------------------------------------
private enum TextSetMode {
case text
case attributedText
}
private var textSetMode: TextSetMode = .text
private var initialSetupPerformed = false
private var edgeInsets: UIEdgeInsets { textStyle.edgeInsets }
@ -102,10 +109,6 @@ open class Label: UILabel, ViewProtocol, UserInfoable {
//--------------------------------------------------
/// Key of whether or not updateView() is called in setNeedsUpdate()
open var shouldUpdateView: Bool = true
/// Determines if the label should use its own attributedText property instead of rendering the attributedText propert
/// based of other local properties, such as textStyle, textColor, surface, etc... The default value is false.
open var useAttributedText: Bool = false
/// Will determine if a scaled font should be used for the font.
open var useScaledFont: Bool = false { didSet { setNeedsUpdate() }}
@ -128,19 +131,40 @@ open class Label: UILabel, ViewProtocol, UserInfoable {
/// Line break mode for the label, default is set to word wrapping.
open override var lineBreakMode: NSLineBreakMode { didSet { setNeedsUpdate() }}
private var _text: String?
/// Text that will be used in the label.
override open var text: String? {
get { _text }
override open var text: String! {
get { super.text }
set {
if _text != newValue || newValue != attributedText?.string {
_text = newValue
useAttributedText = false
attributes?.removeAll()
setNeedsUpdate()
textSetMode = .text
styleText(newValue)
}
}
///AttributedText that will be used in the label.
override open var attributedText: NSAttributedString? {
get { super.attributedText }
set {
textSetMode = .attributedText
styleAttributedText(newValue)
}
}
override open var font: UIFont! {
didSet {
if let font, initialSetupPerformed {
textStyle = TextStyle.convert(font: font)
}
setNeedsUpdate()
}
}
override open var textColor: UIColor! {
didSet {
if let textColor, initialSetupPerformed {
textColorConfiguration = SurfaceColorConfiguration(textColor, textColor).eraseToAnyColorable()
}
setNeedsUpdate()
}
}
@ -162,13 +186,13 @@ open class Label: UILabel, ViewProtocol, UserInfoable {
//--------------------------------------------------
open func initialSetup() {
if !initialSetupPerformed {
initialSetupPerformed = true
//register for ContentSizeChanges
NotificationCenter
.Publisher(center: .default, name: UIContentSizeCategory.didChangeNotification)
.sink { [weak self] notification in
self?.setNeedsUpdate()
}.store(in: &subscribers)
backgroundColor = .clear
numberOfLines = 0
lineBreakMode = .byWordWrapping
@ -200,30 +224,13 @@ open class Label: UILabel, ViewProtocol, UserInfoable {
}
open func updateView() {
if !useAttributedText {
if let text {
accessibilityCustomActions = []
//create the primary string
let mutableText = NSMutableAttributedString.mutableText(for: text,
textStyle: textStyle,
useScaledFont: useScaledFont,
textColor: textColorConfiguration.getColor(self),
alignment: textAlignment,
lineBreakMode: lineBreakMode)
applyAttributes(mutableText)
//set the attributed text
attributedText = mutableText
//force a drawText
setNeedsDisplay()
setNeedsLayout()
layoutIfNeeded()
}
}
restyleText()
//force a drawText
setNeedsDisplay()
setNeedsLayout()
layoutIfNeeded()
}
open func updateAccessibility() {
@ -269,6 +276,56 @@ open class Label: UILabel, ViewProtocol, UserInfoable {
//--------------------------------------------------
// MARK: - Private Methods
//--------------------------------------------------
private func restyleText() {
if textSetMode == .text {
styleText(text)
} else {
styleAttributedText(attributedText)
}
}
private func styleText(_ newValue: String!) {
defer { invalidateIntrinsicContentSize() }
guard let newValue else {
// We don't need to use attributed text
super.attributedText = nil
super.text = newValue
return
}
accessibilityCustomActions = []
//create the primary string
let mutableText = NSMutableAttributedString.mutableText(for: newValue,
textStyle: textStyle,
useScaledFont: useScaledFont,
textColor: textColorConfiguration.getColor(self),
alignment: textAlignment,
lineBreakMode: lineBreakMode)
applyAttributes(mutableText)
// Set attributed text to match typography
super.attributedText = mutableText
}
private func styleAttributedText(_ newValue: NSAttributedString?) {
defer { invalidateIntrinsicContentSize() }
guard let newValue = newValue else {
// We don't need any additional styling
super.attributedText = newValue
return
}
let mutableText = NSMutableAttributedString(attributedString: newValue)
applyAttributes(mutableText)
// Modify attributed text to match typography
super.attributedText = mutableText
}
private func applyAttributes(_ mutableAttributedString: NSMutableAttributedString) {
actions = []

View File

@ -100,7 +100,6 @@ open class RadioBoxItem: Control, Changeable, FormFieldable {
/// If provided, the RadioBox textAttributedText will be rendered.
open var textAttributedText: NSAttributedString? {
didSet {
textLabel.useAttributedText = !(textAttributedText?.string.isEmpty ?? true)
textLabel.attributedText = textAttributedText
setNeedsUpdate()
}
@ -115,7 +114,6 @@ open class RadioBoxItem: Control, Changeable, FormFieldable {
/// If provided, the RadioBox subTextAttributedText will be rendered.
open var subTextAttributedText: NSAttributedString? {
didSet {
subTextLabel.useAttributedText = !(subTextAttributedText?.string.isEmpty ?? true)
subTextLabel.attributedText = subTextAttributedText
setNeedsUpdate()
}
@ -130,7 +128,6 @@ open class RadioBoxItem: Control, Changeable, FormFieldable {
/// If provided, the RadioBox subTextRightAttributedText will be rendered.
open var subTextRightAttributedText: NSAttributedString? {
didSet {
subTextRightLabel.useAttributedText = !(subTextRightAttributedText?.string.isEmpty ?? true)
subTextRightLabel.attributedText = subTextRightAttributedText
setNeedsUpdate()
}

View File

@ -94,6 +94,7 @@ open class TextView: UITextView, ViewProtocol {
//--------------------------------------------------
open func initialSetup() {
if !initialSetupPerformed {
initialSetupPerformed = true
backgroundColor = .clear
translatesAutoresizingMaskIntoConstraints = false
accessibilityCustomActions = []

View File

@ -6,15 +6,17 @@
//
import Foundation
import UIKit
/// Enum that is matched up for the Verizon fonts.
public enum Font: String, FontProtocol {
public enum Font: FontProtocol {
case edsBold
case edsRegular
case dsLight
case etxBold
case etxRegular
case custom(UIFont)
public var fontName: String {
switch self {
case .edsBold:
@ -27,11 +29,32 @@ public enum Font: String, FontProtocol {
return "VerizonNHGeTX-Bold"
case .etxRegular:
return "VerizonNHGeTX-Regular"
case .custom(let font):
return font.fontName
}
}
public static var allCases: [Font] {
[.edsBold, .edsRegular, .dsLight, .etxBold, .etxRegular]
}
/// File Extension for each of the Font enums.
public var fontFileExtension: String {
return "otf"
}
/// Returns a UIFont for the fontName and size given.
/// - Parameters:
/// - size: Size of the font
/// - Returns: UIFont for the fontName and Size.
public func font(ofSize size: CGFloat) -> UIFont{
DispatchQueue.once(block: { self.register() })
switch self {
case .custom(let font):
return font
default:
guard let found = UIFont(name: self.fontName, size: size) else { return .systemFont(ofSize: size) }
return found
}
}
}

View File

@ -9,9 +9,10 @@ import Foundation
import UIKit
/// Used in Classes that require Fonts
public protocol FontProtocol: CaseIterable, RawRepresentable, Hashable {
public protocol FontProtocol {
var fontFileExtension: String { get }
var fontName: String { get }
static var allCases: [Self] { get }
}
extension FontProtocol {

View File

@ -209,6 +209,13 @@ extension TextStyle {
boldMicro
]
}
public static func convert(font: UIFont) -> TextStyle {
guard let found = allCases.first(where: { font.fontName == $0.fontFace.fontName && font.pointSize == $0.pointSize} ) else {
return TextStyle(rawValue: "Custom\(font.fontName)", fontFace: .custom(font), pointSize: font.pointSize)
}
return found
}
}
extension TextStyle {