one column and progress accessibililty logic
This commit is contained in:
parent
b77c7c79e4
commit
7a9f9bd2c5
@ -8,20 +8,30 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
@objcMembers open class ProgressBar: UIProgressView, MVMCoreViewProtocol, MoleculeViewProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
var progressBarModel: ProgressBarModel?
|
||||
|
||||
var thickness: CGFloat = 8.0 {
|
||||
willSet(newValue) {
|
||||
heightAnchor.constraint(equalToConstant: newValue).isActive = true
|
||||
|
||||
if progressBarModel?.roundedCorners ?? false {
|
||||
layer.cornerRadius = newValue/2.0
|
||||
layer.cornerRadius = newValue / 2.0
|
||||
} else {
|
||||
progressViewStyle = .bar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setupView()
|
||||
@ -37,41 +47,49 @@ import Foundation
|
||||
setupView()
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
public func setupView() {
|
||||
|
||||
clipsToBounds = true
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
thickness = 8
|
||||
progress = 0
|
||||
progressTintColor = UIColor.mfCerulean()
|
||||
trackTintColor = UIColor.mfLightSilver()
|
||||
progressTintColor = .mfCerulean()
|
||||
trackTintColor = .mvmCoolGray3
|
||||
}
|
||||
|
||||
public func updateView(_ size: CGFloat) {
|
||||
}
|
||||
public func updateView(_ size: CGFloat) { }
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
//MARK: - MoleculeViewProtocol
|
||||
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
guard let progressBarModel = model as? ProgressBarModel else { return }
|
||||
|
||||
self.progressBarModel = progressBarModel
|
||||
thickness = progressBarModel.thickness ?? 8
|
||||
progress = Float((progressBarModel.percent)/100.0)
|
||||
progress = Float((progressBarModel.percent) / 100.0)
|
||||
progressTintColor = progressBarModel.color.uiColor
|
||||
|
||||
if let backgroundColor = progressBarModel.backgroundColor {
|
||||
trackTintColor = backgroundColor.uiColor
|
||||
}
|
||||
}
|
||||
|
||||
public func reset() {
|
||||
|
||||
thickness = 8
|
||||
progress = 0
|
||||
progressTintColor = UIColor.mfCerulean()
|
||||
trackTintColor = UIColor.mfLightSilver()
|
||||
progressTintColor = .mfCerulean()
|
||||
trackTintColor = .mvmCoolGray3
|
||||
}
|
||||
|
||||
public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 8
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -7,24 +7,28 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
@objcMembers open class ListProgressBarThin: TableViewCell {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
|
||||
public let progressBar = ProgressBar()
|
||||
public let leftHeadline = Label.commonLabelB1(true)
|
||||
public let leftBody = Label.commonLabelB2(true)
|
||||
public let leftHeadline = Label.createLabelBoldBodySmall(true)
|
||||
public let leftBody = Label.createLabelBoldBodySmall(true)
|
||||
public let rightBar = Line()
|
||||
public let rightLabel = Label.commonLabelB2(true)
|
||||
public let rightLabel = Label.createLabelBoldBodySmall(true)
|
||||
private let barStackItem: StackItem
|
||||
private let rightLabelStackItem: StackItem
|
||||
public var labelStack: Stack<StackModel>
|
||||
public var horizontalStack: Stack<StackModel>
|
||||
public var stack: Stack<StackModel>
|
||||
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//------------------------------------------------------
|
||||
|
||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
//vertical stack with leftHeadline, leftBody
|
||||
labelStack = Stack<StackModel>.createStack(with: [leftHeadline, leftBody], axis: .vertical, spacing: 2)
|
||||
@ -34,9 +38,9 @@ import Foundation
|
||||
rightLabelStackItem = StackItem(andContain: rightLabel)
|
||||
let horizontalStackItems = [StackItem(andContain: labelStack), barStackItem, rightLabelStackItem]
|
||||
let horizontalStackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .leading), StackItemModel(horizontalAlignment: .fill), StackItemModel(spacing: 5, horizontalAlignment: .fill)],
|
||||
axis: .horizontal)
|
||||
axis: .horizontal)
|
||||
horizontalStack = Stack<StackModel>(with: horizontalStackModel, stackItems: horizontalStackItems)
|
||||
|
||||
|
||||
//stack with all components
|
||||
stack = Stack<StackModel>.createStack(with: [horizontalStack, progressBar], axis: .vertical, spacing: PaddingDefaultVerticalSpacing3)
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
@ -49,19 +53,23 @@ import Foundation
|
||||
open override func alignAccessoryToHero() -> CGPoint? {
|
||||
// Ensures that the right items are centered with the arrow.
|
||||
let heroCenter = super.alignAccessoryToHero()
|
||||
|
||||
if let heroCenter = heroCenter {
|
||||
let convertedPoint = horizontalStack.convert(heroCenter, from: self)
|
||||
barStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - horizontalStack.bounds.midY
|
||||
rightLabelStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - horizontalStack.bounds.midY
|
||||
}
|
||||
|
||||
return heroCenter
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - View Lifecycle
|
||||
// MARK: - Lifecycle
|
||||
//-------------------------------------------------------
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
|
||||
rightBar.widthAnchor.constraint(equalToConstant: 20).isActive = true
|
||||
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
|
||||
rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal)
|
||||
@ -70,19 +78,24 @@ import Foundation
|
||||
stack.restack()
|
||||
horizontalStack.restack()
|
||||
labelStack.restack()
|
||||
isAccessibilityElement = true
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Molecule
|
||||
//------------------------------------------------------
|
||||
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)
|
||||
|
||||
guard let model = model as? ListProgressBarThinModel else { return }
|
||||
labelStack.updateContainedMolecules(with: [model.leftHeadline,
|
||||
model.leftBody], delegateObject, additionalData)
|
||||
|
||||
labelStack.updateContainedMolecules(with: [model.leftHeadline, model.leftBody], delegateObject, additionalData)
|
||||
progressBar.set(with: model.progressBar, delegateObject, additionalData)
|
||||
rightBar.set(with: model.rightBar, delegateObject, additionalData)
|
||||
rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
@ -96,4 +109,31 @@ import Foundation
|
||||
rightLabel.styleB2(true)
|
||||
rightBar.setStyle(.medium)
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Accessibility
|
||||
//------------------------------------------------------
|
||||
|
||||
func updateAccessibilityLabel() {
|
||||
|
||||
var message = ""
|
||||
|
||||
if let leftHeadlineText = leftHeadline.text {
|
||||
message += leftHeadlineText + ", "
|
||||
}
|
||||
|
||||
if let leftBodyText = leftBody.text {
|
||||
message += leftBodyText + ", "
|
||||
}
|
||||
|
||||
if let progressLabel = progressBar.accessibilityLabel, let progressValue = progressBar.accessibilityValue {
|
||||
message += progressLabel + ", " + progressValue + ", "
|
||||
}
|
||||
|
||||
if let rightLabelText = rightLabel.text {
|
||||
message += rightLabelText + ", "
|
||||
}
|
||||
|
||||
accessibilityLabel = message
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,13 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
public class ListProgressBarThinModel: ListItemModel, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier = "listPrgBarThin"
|
||||
public var progressBar: ProgressBarModel
|
||||
public var leftHeadline: LabelModel
|
||||
@ -15,6 +21,10 @@ public class ListProgressBarThinModel: ListItemModel, MoleculeModelProtocol {
|
||||
public var rightBar: LineModel
|
||||
public var rightLabel: LabelModel
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(progressBar: ProgressBarModel, leftHeadline: LabelModel, leftBody: LabelModel? = nil, rightBar: LineModel, rightLabel: LabelModel) {
|
||||
self.progressBar = progressBar
|
||||
self.leftHeadline = leftHeadline
|
||||
@ -24,15 +34,26 @@ public class ListProgressBarThinModel: ListItemModel, MoleculeModelProtocol {
|
||||
super.init()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Method
|
||||
//--------------------------------------------------
|
||||
|
||||
override public func setDefaults() {
|
||||
super.setDefaults()
|
||||
|
||||
rightBar.type = .medium
|
||||
|
||||
if rightBar.backgroundColor == nil {
|
||||
rightBar.backgroundColor = Color(uiColor: .gray)
|
||||
}
|
||||
|
||||
leftHeadline.hero = 0
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case progressBar
|
||||
@ -42,6 +63,10 @@ public class ListProgressBarThinModel: ListItemModel, MoleculeModelProtocol {
|
||||
case rightLabel
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
public required init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
progressBar = try typeContainer.decode(ProgressBarModel.self, forKey:.progressBar)
|
||||
|
||||
@ -43,17 +43,17 @@ import Foundation
|
||||
super.setupView()
|
||||
addMolecule(stack)
|
||||
stack.restack()
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
|
||||
guard let model = model as? ListOneColumnFullWidthTextAllTextAndLinksModel else { return }
|
||||
stack.updateContainedMolecules(with: [model.eyebrow,
|
||||
model.headline,
|
||||
model.subHeadline,
|
||||
model.body,
|
||||
model.link],
|
||||
|
||||
stack.updateContainedMolecules(with: [model.eyebrow, model.headline, model.subHeadline, model.body, model.link],
|
||||
delegateObject, additionalData)
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
@ -67,4 +67,60 @@ import Foundation
|
||||
subHeadline.styleBoldBodySmall(true)
|
||||
body.styleRegularBodySmall(true)
|
||||
}
|
||||
|
||||
func updateAccessibilityLabel() {
|
||||
|
||||
var message = ""
|
||||
|
||||
if let eyebrowLabel = eyebrow.text {
|
||||
message += eyebrowLabel + ", "
|
||||
}
|
||||
|
||||
if let headlineLabel = headline.text {
|
||||
message += headlineLabel + ", "
|
||||
}
|
||||
|
||||
if let headlineLabel = headline.text {
|
||||
message += headlineLabel + ", "
|
||||
}
|
||||
|
||||
if let bodyLabel = body.text {
|
||||
message += bodyLabel
|
||||
}
|
||||
|
||||
let linkShowing = link.titleLabel?.text?.count ?? 0 > 0
|
||||
isAccessibilityElement = !linkShowing
|
||||
link.isAccessibilityElement = linkShowing
|
||||
|
||||
if !linkShowing {
|
||||
// Make whole cell focusable if no link.
|
||||
accessibilityLabel = message
|
||||
} else {
|
||||
// Allow only radio button and link to be focused on.
|
||||
var elements: [UIView] = []
|
||||
|
||||
|
||||
if let eyeBrowText = eyebrow.text, !eyeBrowText.isEmpty {
|
||||
elements.append(eyebrow)
|
||||
}
|
||||
|
||||
if let headlineText = headline.text, !headlineText.isEmpty {
|
||||
elements.append(headline)
|
||||
}
|
||||
|
||||
if let subHeadlineText = subHeadline.text, !subHeadlineText.isEmpty {
|
||||
elements.append(subHeadline)
|
||||
}
|
||||
|
||||
if let bodyText = body.text, !bodyText.isEmpty {
|
||||
elements.append(body)
|
||||
}
|
||||
|
||||
if linkShowing {
|
||||
elements.append(link)
|
||||
}
|
||||
|
||||
accessibilityElements = elements
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,12 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
public class ListOneColumnFullWidthTextAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "list1CTxt"
|
||||
public var eyebrow: LabelModel?
|
||||
public var headline : LabelModel?
|
||||
@ -16,6 +21,10 @@ public class ListOneColumnFullWidthTextAllTextAndLinksModel: ListItemModel, Mole
|
||||
public var body: LabelModel?
|
||||
public var link : LinkModel?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(eyebrow: LabelModel? = nil, headline: LabelModel? = nil, subHeadline: LabelModel? = nil, body: LabelModel? = nil, link: LinkModel? = nil) {
|
||||
self.eyebrow = eyebrow
|
||||
self.headline = headline
|
||||
@ -25,6 +34,10 @@ public class ListOneColumnFullWidthTextAllTextAndLinksModel: ListItemModel, Mole
|
||||
super.init()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case eyebrow
|
||||
@ -34,6 +47,10 @@ public class ListOneColumnFullWidthTextAllTextAndLinksModel: ListItemModel, Mole
|
||||
case link
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow)
|
||||
|
||||
@ -8,28 +8,55 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
@objcMembers open class ListOneColumnFullWidthTextBodyText: TableViewCell {
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//-----------------------------------------------------
|
||||
public var headlineBody = HeadlineBody(frame: .zero)
|
||||
|
||||
public var headlineBody = HeadlineBody()
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - View Lifecycle
|
||||
// MARK: - Lifecycle
|
||||
//-----------------------------------------------------
|
||||
|
||||
override open func setupView() {
|
||||
super.setupView()
|
||||
|
||||
addMolecule(headlineBody)
|
||||
isAccessibilityElement = true
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
guard let model = model as? ListOneColumnFullWidthTextBodyTextModel else { return }
|
||||
|
||||
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 90
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Accessibility
|
||||
//-----------------------------------------------------
|
||||
|
||||
func updateAccessibilityLabel() {
|
||||
|
||||
var message = ""
|
||||
|
||||
if let headlineLabel = headlineBody.headlineLabel.text {
|
||||
message += headlineLabel + ", "
|
||||
}
|
||||
|
||||
if let messageLabel = headlineBody.messageLabel.text {
|
||||
message += messageLabel
|
||||
}
|
||||
|
||||
accessibilityLabel = message
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,26 +8,46 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
public class ListOneColumnFullWidthTextBodyTextModel: ListItemModel, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "list1CFWBdy"
|
||||
public var headlineBody: HeadlineBodyModel
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializier
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(headlineBody: HeadlineBodyModel) {
|
||||
self.headlineBody = headlineBody
|
||||
super.init()
|
||||
}
|
||||
|
||||
// Defaults to set
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
override public func setDefaults() {
|
||||
super.setDefaults()
|
||||
headlineBody.style = .item
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case headlineBody
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user