Merge branch 'feature/titlelockup_clean' into 'feature/3.0-TitleLockup'

Switch to UIStackView for simplicity.

See merge request BPHV_MIPS/mvm_core_ui!869
This commit is contained in:
Pfeil, Scott Robert 2022-06-22 00:05:17 +00:00
commit 7c23b9f073
2 changed files with 103 additions and 95 deletions

View File

@ -14,11 +14,11 @@
public let eyebrow = Label(fontStyle: .RegularBodySmall) public let eyebrow = Label(fontStyle: .RegularBodySmall)
public let title = Label(fontStyle: .RegularBodySmall) public let title = Label(fontStyle: .RegularBodySmall)
public let subTitle = Label(fontStyle: .RegularBodySmall) public let subTitle = Label(fontStyle: .RegularBodySmall)
public lazy var stack: Stack<StackModel> = { public lazy var stack: UIStackView = {
return Stack<StackModel>.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .fill)), let stack = UIStackView(arrangedSubviews: [eyebrow, title, subTitle])
(view: title, model: StackItemModel(horizontalAlignment: .fill)), stack.translatesAutoresizingMaskIntoConstraints = false
(view: subTitle, model: StackItemModel(horizontalAlignment: .fill))], stack.axis = .vertical
axis: .vertical) return stack
}() }()
var castModel: TitleLockupModel? { var castModel: TitleLockupModel? {
@ -41,12 +41,10 @@
super.setupView() super.setupView()
addSubview(stack) addSubview(stack)
NSLayoutConstraint.constraintPinSubview(toSuperview: stack) NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
stack.restack()
} }
open override func updateView(_ size: CGFloat) { open override func updateView(_ size: CGFloat) {
super.updateView(size) super.updateView(size)
stack.stackModel?.spacing = castModel?.style.defaultSpacing() ?? TitleLockupModel.Style.large.defaultSpacing()
stack.updateView(size) stack.updateView(size)
} }
@ -66,7 +64,8 @@
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData) super.set(with: model, delegateObject, additionalData)
guard let model = model as? TitleLockupModel else { return } guard let model = model as? TitleLockupModel else { return }
stack.setCustomSpacing(model.defaultEyebrowTitleSpacing(), after: eyebrow)
stack.setCustomSpacing(model.defaultTitleSubTitleSpacing(), after: title)
stack.updateContainedMolecules(with: [model.eyebrow, stack.updateContainedMolecules(with: [model.eyebrow,
model.title, model.title,
model.subTitle], model.subTitle],

View File

@ -21,9 +21,25 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco
public var title: LabelModel public var title: LabelModel
public var subTitle: LabelModel? public var subTitle: LabelModel?
public var style: Style = .large public var alignment: Alignment = .left {
public var alignment: Alignment = .left didSet {
public var inverted: Bool = false ///Updating the text alignment for all labels
if let textAlignment = NSTextAlignment(rawValue: alignment.rawValue) {
eyebrow?.textAlignment = textAlignment
title.textAlignment = textAlignment
subTitle?.textAlignment = textAlignment
}
}
}
public var inverted: Bool = false {
didSet {
///Updating the text color
eyebrow?.textColor = titleColor
title.textColor = titleColor
subTitle?.textColor = subTitleColor
}
}
private var _backgroundColor: Color? private var _backgroundColor: Color?
public var backgroundColor: Color? { public var backgroundColor: Color? {
@ -52,68 +68,63 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco
//-------------------------------------------------- //--------------------------------------------------
public init(eyebrow: LabelModel? = nil, title: LabelModel, subTitle: LabelModel? = nil) throws { public init(eyebrow: LabelModel? = nil, title: LabelModel, subTitle: LabelModel? = nil) throws {
self.eyebrow = eyebrow self.eyebrow = eyebrow
self.title = title self.title = title
self.subTitle = subTitle self.subTitle = subTitle
updateLabelAttributes()
} }
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Enum // MARK: - Enum
//-------------------------------------------------- //--------------------------------------------------
/// Convenience styles for common situations.
public enum Style: String, Codable {
case small
case medium
case large
case xlarge
case xxlarge
func defaultHeadlineFontStyle() -> Styler.Font {
switch self {
case .small:
return .BoldBodyLarge
case .medium:
return .BoldTitleMedium
case .large:
return .BoldTitleLarge
case .xlarge:
return .TitleXLarge
case .xxlarge:
return .Title2XLarge
}
}
func defaultBodyFontStyle() -> Styler.Font {
switch self {
case .small,.medium,.large:
return .RegularBodySmall
case .xlarge,.xxlarge:
return .RegularBodyLarge
}
}
func defaultSpacing() -> CGFloat {
switch self {
case .small,.medium,.large:
return Padding.Two
case .xlarge:
return Padding.Three
case .xxlarge:
return Padding.Four
}
}
}
public enum Alignment: String, Codable { public enum Alignment: String, Codable {
case left case left
case center case center
} }
//--------------------------------------------------
// MARK: - Styling
//--------------------------------------------------
/// Returns the default fontStyle for the subtitle, based on the title fontStyle.
func defaultSubtitleFontStyle() -> Styler.Font {
switch title.fontStyle {
case .RegularTitleXLarge, .RegularTitle2XLarge, .RegularFeatureXSmall:
return .RegularBodyLarge
case .RegularFeatureSmall, .RegularFeatureMedium:
return .RegularTitleLarge
default:
return .RegularBodySmall
}
}
/// Returns the default spacing between the eyebrow and title, based on the title fontStyle.
func defaultEyebrowTitleSpacing() -> CGFloat {
switch title.fontStyle {
case .RegularTitleXLarge, .RegularTitle2XLarge, .RegularFeatureXSmall, .RegularFeatureSmall:
return Padding.Three
case .RegularFeatureMedium:
return subTitle?.fontStyle == .RegularBodyLarge ? Padding.Three : Padding.Four
default:
return Padding.Two
}
}
/// Returns the default spacing between the title and subTitle, based on the title fontStyle.
func defaultTitleSubTitleSpacing() -> CGFloat {
switch title.fontStyle {
case .RegularTitleXLarge:
return Padding.Three
case .RegularTitle2XLarge, .RegularFeatureXSmall, .RegularFeatureSmall:
return Padding.Four
case .RegularFeatureMedium:
return Padding.Five
default:
return Padding.Two
}
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Keys // MARK: - Keys
//-------------------------------------------------- //--------------------------------------------------
@ -126,7 +137,6 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco
case subTitle case subTitle
case inverted case inverted
case alignment case alignment
case style
} }
//-------------------------------------------------- //--------------------------------------------------
@ -135,14 +145,9 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco
required public init(from decoder: Decoder) throws { required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self) let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow)
title = try typeContainer.decodeMolecule(codingKey: .title) title = try typeContainer.decodeMolecule(codingKey: .title)
eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow)
subTitle = try typeContainer.decodeMoleculeIfPresent(codingKey: .subTitle) subTitle = try typeContainer.decodeMoleculeIfPresent(codingKey: .subTitle)
if let newStyle = try typeContainer.decodeIfPresent(Style.self, forKey: .style) {
style = newStyle
setStyle(style: newStyle)
}
if let newAlignment = try typeContainer.decodeIfPresent(Alignment.self, forKey: .alignment) { if let newAlignment = try typeContainer.decodeIfPresent(Alignment.self, forKey: .alignment) {
alignment = newAlignment alignment = newAlignment
@ -151,7 +156,9 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco
if let invertedStatus = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { if let invertedStatus = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
inverted = invertedStatus inverted = invertedStatus
} }
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
updateLabelAttributes() updateLabelAttributes()
} }
@ -161,7 +168,6 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco
try container.encodeIfPresent(eyebrow, forKey: .eyebrow) try container.encodeIfPresent(eyebrow, forKey: .eyebrow)
try container.encodeModel(title, forKey: .title) try container.encodeModel(title, forKey: .title)
try container.encodeIfPresent(subTitle, forKey: .subTitle) try container.encodeIfPresent(subTitle, forKey: .subTitle)
try container.encodeIfPresent(style, forKey: .style)
try container.encode(alignment, forKey: .alignment) try container.encode(alignment, forKey: .alignment)
try container.encode(inverted, forKey: .inverted) try container.encode(inverted, forKey: .inverted)
try container.encodeIfPresent(_backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(_backgroundColor, forKey: .backgroundColor)
@ -170,37 +176,40 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Model updates // MARK: - Model updates
//-------------------------------------------------- //--------------------------------------------------
private func setStyle(style: Style) {
///If eyebrow style is not available, will set font style based on the component
///Eyebrow and body share the same font size
if eyebrow?.fontStyle == nil {
eyebrow?.fontStyle = style.defaultBodyFontStyle()
}
///If title style is not available, will set font style based on the component
if title.fontStyle == nil {
title.fontStyle = style.defaultHeadlineFontStyle()
}
///If subtitle style is not available, will set font style based on the component
if subTitle?.fontStyle == nil {
subTitle?.fontStyle = style.defaultBodyFontStyle()
}
}
private func updateLabelAttributes() { private func updateLabelAttributes() {
///Updating the text color // If subtitle style is not available, will set font style based on the component
eyebrow?.textColor = titleColor if subTitle?.fontStyle == nil {
title.textColor = titleColor subTitle?.fontStyle = defaultSubtitleFontStyle()
subTitle?.textColor = subTitleColor }
///Updating the text alignment for all labels // If eyebrow style is not available, will set font style based on the component. Eyebrow and subtitle share the same font size
if eyebrow?.fontStyle == nil {
eyebrow?.fontStyle = subTitle?.fontStyle
}
// Updating the text color
if eyebrow?.textColor == nil {
eyebrow?.textColor = subTitleColor
}
if title.textColor == nil {
title.textColor = titleColor
}
if subTitle?.textColor == nil {
subTitle?.textColor = subTitleColor
}
// Updating the text alignment for all labels
if let textAlignment = NSTextAlignment(rawValue: alignment.rawValue) { if let textAlignment = NSTextAlignment(rawValue: alignment.rawValue) {
eyebrow?.textAlignment = textAlignment if eyebrow?.textAlignment == nil {
title.textAlignment = textAlignment eyebrow?.textAlignment = textAlignment
subTitle?.textAlignment = textAlignment }
if title.textAlignment == nil {
title.textAlignment = textAlignment
}
if subTitle?.textAlignment == nil {
subTitle?.textAlignment = textAlignment
}
} }
} }
} }