diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryField.swift index fa880a50..65c4448b 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryField.swift @@ -75,11 +75,8 @@ extension BaseItemPickerEntryField { @objc open override func setAccessibilityString(_ accessibilityString: String?) { var accessibilityString = accessibilityString ?? "" - - if let textPickerItem = MVMCoreUIUtility.hardcodedString(withKey: "textfield_picker_item") { - accessibilityString += textPickerItem - } - + textField.accessibilityTraits = .staticText + textField.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "textfield_picker_item") textField.accessibilityLabel = "\(accessibilityString) \(textField.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state") ?? "")" } } diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryField.swift index 18749c8a..a40aa56f 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryField.swift @@ -379,7 +379,7 @@ import UIKit if let text = model.text, !text.isEmpty { regexTextFieldOutputIfAvailable() } - + setAccessibilityString(model.title ?? "") } } @@ -399,10 +399,6 @@ extension TextEntryField { var accessibilityString = accessibilityString ?? "" - if let txtRegular = MVMCoreUIUtility.hardcodedString(withKey: "textfield_regular") { - accessibilityString += txtRegular - } - textField.accessibilityLabel = "\(accessibilityString) \(textField.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state") ?? "")" } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabel.swift b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabel.swift index 88ee69be..965656a6 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabel.swift @@ -14,6 +14,7 @@ public let checkbox = Checkbox() public let label = Label(fontStyle: .RegularBodySmall) + private var observation: NSKeyValueObservation? = nil //-------------------------------------------------- // MARK: - Properties @@ -63,6 +64,12 @@ bottomLabelConstraint.isActive = true alignCheckbox(.center) + isAccessibilityElement = true + accessibilityHint = checkbox.accessibilityHint + accessibilityTraits = checkbox.accessibilityTraits + observation = observe(\.checkbox.isSelected, options: [.new]) { [weak self] _, _ in + self?.updateAccessibilityLabel() + } } @objc override open func updateView(_ size: CGFloat) { @@ -111,6 +118,7 @@ checkbox.set(with: checkBoxWithLabelModel.checkbox, delegateObject, additionalData) label.set(with: checkBoxWithLabelModel.label, delegateObject, additionalData) + updateAccessibilityLabel() } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { @@ -124,4 +132,13 @@ checkbox.reset() alignCheckbox(.center) } + + override open func accessibilityActivate() -> Bool { + checkbox.accessibilityActivate() + } + + open func updateAccessibilityLabel() { + checkbox.updateAccessibilityLabel() + accessibilityLabel = [checkbox.accessibilityLabel, label.text].compactMap { $0 }.joined(separator: ",") + } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift index 1b5b0697..55ae3e02 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift @@ -20,7 +20,7 @@ //-------------------------------------------------- public var stack: Stack - + public var model: MoleculeModelProtocol? private var observation: NSKeyValueObservation? = nil //-------------------------------------------------- @@ -68,6 +68,7 @@ checkbox.set(with: model.checkbox, delegateObject, additionalData) eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + self.model = model updateAccessibilityLabel() } @@ -93,7 +94,7 @@ message += label } - let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0 + let linkShowing = (model as? ListLeftVariableCheckboxAllTextAndLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil isAccessibilityElement = !linkShowing if !linkShowing { // Make whole cell focusable if no link. diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinks.swift index 728d8464..78b91f9f 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinks.swift @@ -15,6 +15,7 @@ public let leftImage = LoadImageView(pinnedEdges: .all) public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink() public var stack: Stack + public var model: MoleculeModelProtocol? //-------------------------------------------------- // MARK: - Initializers @@ -53,6 +54,7 @@ leftImage.set(with: model.image, delegateObject, additionalData) eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + self.model = model updateAccessibilityLabel() } @@ -75,7 +77,7 @@ func updateAccessibilityLabel() { - let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0 + let linkShowing = (model as? ListLeftVariableIconAllTextLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil isAccessibilityElement = !linkShowing accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretAllTextLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretAllTextLinks.swift index 0c09e9e3..683ef1ab 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretAllTextLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretAllTextLinks.swift @@ -14,7 +14,7 @@ public let leftImage = LoadImageView(pinnedEdges: .all) public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(spacing: 2.0) public let rightLabel = Label(fontStyle: .RegularBodySmall) - + public var model: MoleculeModelProtocol? public lazy var rightLabelStackItem: StackItem = { return StackItem(andContain: rightLabel) }() @@ -66,6 +66,7 @@ leftImage.set(with: model.image, delegateObject, additionalData) eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) rightLabel.set(with: model.rightLabel, delegateObject, additionalData) + self.model = model updateAccessibilityLabel() } @@ -97,7 +98,7 @@ } func updateAccessibilityLabel() { - let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0 + let linkShowing = (model as? ListLeftVariableIconWithRightCaretAllTextLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil isAccessibilityElement = !linkShowing accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift index 75096854..f3afc623 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift @@ -15,6 +15,7 @@ public let leftLabel = Label(fontStyle: .Title2XLarge) public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink() public var stack: Stack + public var model: MoleculeModelProtocol? //-------------------------------------------------- // MARK: - Initializers @@ -54,6 +55,7 @@ leftLabel.text = String(model.number) eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + self.model = model updateAccessibilityLabel() } @@ -85,7 +87,7 @@ func updateAccessibilityLabel() { - let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0 + let linkShowing = (model as? ListLeftVariableNumberedListAllTextAndLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil isAccessibilityElement = !linkShowing accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAllTextAndLinks.swift index 730f988f..cc3e57d6 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAllTextAndLinks.swift @@ -15,7 +15,7 @@ let radioButton = RadioButton() let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink() var stack: Stack - + public var model: MoleculeModelProtocol? private var observation: NSKeyValueObservation? = nil //----------------------------------------------------- @@ -62,6 +62,7 @@ radioButton.set(with: model.radioButton, delegateObject, additionalData) eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + self.model = model updateAccessibilityLabel() } @@ -91,7 +92,7 @@ message += label } - let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0 + let linkShowing = (model as? ListLeftVariableRadioButtonAllTextAndLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil isAccessibilityElement = !linkShowing if !linkShowing { // Make whole cell focusable if no link. diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift index 48e3c49c..b749355d 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift @@ -18,7 +18,7 @@ import UIKit let leftImage = LoadImageView(pinnedEdges: .all) let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink() var stack: Stack - + public var model: MoleculeModelProtocol? private var observation: NSKeyValueObservation? = nil //----------------------------------------------------- @@ -79,6 +79,7 @@ import UIKit radioButton.set(with: model.radioButton, delegateObject, additionalData) leftImage.set(with: model.image, delegateObject, additionalData) eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + self.model = model updateAccessibilityLabel() } @@ -112,7 +113,7 @@ import UIKit message += label } - let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0 + let linkShowing = (model as? ListLeftVariableRadioButtonAndPaymentMethodModel)?.eyebrowHeadlineBodyLink.link?.title != nil isAccessibilityElement = !linkShowing if !linkShowing { // Make whole cell focusable if no link. diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift index 6e5a7245..c2c13089 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift @@ -20,6 +20,7 @@ import Foundation let subHeadline = Label(fontStyle: .BoldBodySmall) let body = Label(fontStyle: .RegularBodySmall) let link = Link() + public var model: MoleculeModelProtocol? //----------------------------------------------------- // MARK: - Initializers @@ -52,6 +53,7 @@ import Foundation stack.updateContainedMolecules(with: [model.eyebrow, model.headline, model.subHeadline, model.body, model.link], delegateObject, additionalData) + self.model = model updateAccessibilityLabel() } @@ -102,7 +104,7 @@ import Foundation func updateAccessibilityLabel() { - let linkShowing = link.titleLabel?.text?.count ?? 0 > 0 + let linkShowing = (model as? ListOneColumnFullWidthTextAllTextAndLinksModel)?.link?.title != nil isAccessibilityElement = !linkShowing if !linkShowing { // Make whole cell focusable if no link. diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift index d0b2ff70..4194d112 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift @@ -18,6 +18,7 @@ private let stack: Stack private let arrowStackItem: StackItem private let rightLabelStackItem: StackItem + public var model: MoleculeModelProtocol? //----------------------------------------------------- // MARK: - Initializers @@ -73,6 +74,7 @@ eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) rightLabel.set(with: model.rightLabel, delegateObject, additionalData) arrow.set(with: model.arrow, delegateObject, additionalData) + self.model = model updateAccessibilityLabel() } @@ -98,7 +100,7 @@ func updateAccessibilityLabel() { - let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0 + let linkShowing = (model as? ListRightVariablePriceChangeAllTextAndLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil isAccessibilityElement = !linkShowing accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableRightCaretAlltextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableRightCaretAlltextAndLinks.swift index 12f11b9e..7048a536 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableRightCaretAlltextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableRightCaretAlltextAndLinks.swift @@ -15,6 +15,7 @@ public let rightLabel = Label(fontStyle: .RegularBodySmall) public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink() public var stack: Stack + public var model: MoleculeModelProtocol? //-------------------------------------------------- // MARK: - Initializers @@ -65,6 +66,7 @@ guard let model = model as? ListRightVariableRightCaretAllTextAndLinksModel else { return } rightLabel.set(with: model.rightLabel, delegateObject, additionalData) eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + self.model = model updateAccessibilityLabel() } @@ -95,7 +97,7 @@ func updateAccessibilityLabel() { - let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0 + let linkShowing = (model as? ListRightVariableRightCaretAllTextAndLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil isAccessibilityElement = !linkShowing accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none diff --git a/MVMCoreUI/Atomic/Organisms/Stack.swift b/MVMCoreUI/Atomic/Organisms/Stack.swift index 1f35e34d..d5de925c 100644 --- a/MVMCoreUI/Atomic/Organisms/Stack.swift +++ b/MVMCoreUI/Atomic/Organisms/Stack.swift @@ -48,13 +48,6 @@ open class Stack: Container where T: (StackModelProtocol & MoleculeModelProto } isAccessibilityElement = false - var accessibleViews: [Any] = [] - - for (index, view) in stackItems.enumerated() where !stackModel.molecules[index].gone { - accessibleViews.append(view) - } - - accessibilityElements = accessibleViews } /// Removes all stack items views from the view. diff --git a/MVMCoreUI/BaseControllers/MFLoadingViewController.m b/MVMCoreUI/BaseControllers/MFLoadingViewController.m index 56ad6d3b..79565df2 100644 --- a/MVMCoreUI/BaseControllers/MFLoadingViewController.m +++ b/MVMCoreUI/BaseControllers/MFLoadingViewController.m @@ -12,11 +12,13 @@ #import "UIColor+MFConvenience.h" #import "MFStyler.h" #import "MVMCoreUICommonViewsUtility.h" +#import @interface MFLoadingViewController () @property (nullable, weak, nonatomic) MFLoadingSpinner *activityIndicator; @property (nullable, weak, nonatomic) UIView *transparentBackgroundView; +@property (nullable, weak, nonatomic) Label *indicatorText; @end @@ -27,23 +29,41 @@ view.backgroundColor = [UIColor clearColor]; self.view = view; + UIStackView *loadingStack = [[UIStackView alloc] initWithFrame:CGRectZero]; + loadingStack.axis = UILayoutConstraintAxisVertical; + loadingStack.alignment = UIStackViewAlignmentCenter; + loadingStack.spacing = 20; + // Sets up the loading view. MFLoadingSpinner *activityIndicatorView = [[MFLoadingSpinner alloc] initWithFrame:CGRectMake(0, 0, 36, 36)]; activityIndicatorView.backgroundColor = [UIColor clearColor]; activityIndicatorView.translatesAutoresizingMaskIntoConstraints = NO; - [view addSubview:activityIndicatorView]; self.activityIndicator = activityIndicatorView; self.activityIndicator.accessibilityIdentifier = @"Loader"; [activityIndicatorView pinWidthAndHeight]; + Label *infoLabel = [Label label]; + infoLabel.textAlignment = NSTextAlignmentCenter; + infoLabel.translatesAutoresizingMaskIntoConstraints = NO; + infoLabel.hidden = true; + self.indicatorText = infoLabel; + + [loadingStack addArrangedSubview:infoLabel]; + [loadingStack addArrangedSubview:activityIndicatorView]; + + loadingStack.translatesAutoresizingMaskIntoConstraints = NO; + [view addSubview:loadingStack]; // Sets the constraints for the activityIndicatorView - [NSLayoutConstraint constraintPinSubview:activityIndicatorView pinCenterX:YES pinCenterY:YES]; + + [NSLayoutConstraint constraintWithItem:infoLabel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0 constant:1.0]; + [NSLayoutConstraint constraintPinSubview:loadingStack pinCenterX:YES pinCenterY:YES]; + [NSLayoutConstraint constraintPinSubview:loadingStack pinTop:NO topConstant:0 pinBottom:NO bottomConstant:0 pinLeft:YES leftConstant:0 pinRight:YES rightConstant:0]; // Sets up the transparent background view. UIView *transparentBackground = [MVMCoreUICommonViewsUtility commonView]; transparentBackground.backgroundColor = [UIColor mfBackgroundGray]; transparentBackground.alpha = 0.9; - [view insertSubview:transparentBackground belowSubview:activityIndicatorView]; + [view insertSubview:transparentBackground belowSubview:loadingStack]; self.transparentBackgroundView = transparentBackground; // Sets the constraints of the transparent background view to be the same as the activity indicator view. @@ -61,8 +81,24 @@ [self.activityIndicator resumeSpinner]; } +- (void)startLoadingWith:(nullable NSAttributedString *) text{ + if(text != nil){ + self.indicatorText.attributedText = text; + self.indicatorText.accessibilityLabel = text.string; + self.indicatorText.hidden = false; + } else { + self.indicatorText.attributedText = nil; + self.indicatorText.accessibilityLabel = @""; + self.indicatorText.hidden = true; + } + [self.activityIndicator resumeSpinner]; +} + - (void)stopLoading { [self.activityIndicator pauseSpinner]; + self.indicatorText.hidden = true; + self.indicatorText.attributedText = nil; + self.indicatorText.accessibilityLabel = @""; } @end diff --git a/MVMCoreUI/Styles/MFStyler.m b/MVMCoreUI/Styles/MFStyler.m index e65fddc5..c77e447d 100644 --- a/MVMCoreUI/Styles/MFStyler.m +++ b/MVMCoreUI/Styles/MFStyler.m @@ -17,7 +17,7 @@ #import CGFloat const PaddingDefault = 24; -CGFloat const PaddingDefaultHorizontalSpacing = 32; +CGFloat const PaddingDefaultHorizontalSpacing = 16; CGFloat const PaddingDefaultVerticalSpacing = 32; CGFloat const PaddingDefaultVerticalSpacing3 = 24; CGFloat const PaddingBetweenFields = 24;