Merge branch 'feature/apo_accessibility' into 'develop'

APO accessibility

See merge request BPHV_MIPS/mvm_core_ui!332
This commit is contained in:
Pan, Xinlei (Ryan) 2020-03-30 12:13:27 -04:00
commit f03f007bbb
14 changed files with 146 additions and 46 deletions

View File

@ -158,6 +158,7 @@ import MVMCore
super.init(frame: frame) super.init(frame: frame)
accessibilityTraits = .button accessibilityTraits = .button
isAccessibilityElement = true
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "checkbox_action_hint") accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "checkbox_action_hint")
updateAccessibilityLabel() updateAccessibilityLabel()
} }
@ -198,8 +199,6 @@ import MVMCore
open override func setupView() { open override func setupView() {
super.setupView() super.setupView()
guard constraints.isEmpty else { return }
isUserInteractionEnabled = true isUserInteractionEnabled = true
translatesAutoresizingMaskIntoConstraints = false translatesAutoresizingMaskIntoConstraints = false
backgroundColor = .clear backgroundColor = .clear
@ -390,8 +389,6 @@ import MVMCore
widthConstraint?.constant = dimension widthConstraint?.constant = dimension
heightConstraint?.constant = dimension heightConstraint?.constant = dimension
} }
//layoutIfNeeded()
} }
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {

View File

@ -323,6 +323,7 @@ public typealias ActionBlock = () -> ()
text = labelModel.text text = labelModel.text
hero = labelModel.hero hero = labelModel.hero
Label.setLabel(self, withHTML: labelModel.html) Label.setLabel(self, withHTML: labelModel.html)
isAccessibilityElement = hasText
switch labelModel.textAlignment { switch labelModel.textAlignment {
case .center: case .center:
@ -429,6 +430,7 @@ public typealias ActionBlock = () -> ()
continue continue
} }
} }
attributedText = attributedString attributedText = attributedString
originalAttributedString = attributedText originalAttributedString = attributedText
} }

View File

@ -127,6 +127,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
private var widthConstraint: NSLayoutConstraint? private var widthConstraint: NSLayoutConstraint?
private func constrainKnob() { private func constrainKnob() {
knobLeadingConstraint?.isActive = !isOn knobLeadingConstraint?.isActive = !isOn
knobTrailingConstraint?.isActive = isOn knobTrailingConstraint?.isActive = isOn
} }
@ -189,8 +190,11 @@ public typealias ActionBlockConfirmation = () -> (Bool)
public override func setupView() { public override func setupView() {
super.setupView() super.setupView()
guard subviews.isEmpty else { return } guard subviews.isEmpty else { return }
isAccessibilityElement = true
accessibilityTraits = .button
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccToggleHint")
accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel")
heightConstraint = heightAnchor.constraint(equalToConstant: Self.containerSize.height) heightConstraint = heightAnchor.constraint(equalToConstant: Self.containerSize.height)
heightConstraint?.isActive = true heightConstraint?.isActive = true
@ -214,8 +218,6 @@ public typealias ActionBlockConfirmation = () -> (Bool)
knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 1) knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 1)
knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1) knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1)
knobLeadingConstraint?.isActive = true knobLeadingConstraint?.isActive = true
accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel")
} }
public override func reset() { public override func reset() {
@ -336,15 +338,13 @@ public typealias ActionBlockConfirmation = () -> (Bool)
// MARK:- MoleculeViewProtocol // MARK:- MoleculeViewProtocol
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let toggleModel = model as? ToggleModel else { super.set(with: model, delegateObject, additionalData)
return
}
self.model = model
self.delegateObject = delegateObject self.delegateObject = delegateObject
FormValidator.setupValidation(molecule: toggleModel, delegate: delegateObject?.formHolderDelegate)
guard let model = model as? ToggleModel else { return } guard let model = model as? ToggleModel else { return }
FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate)
if let color = model.onTintColor?.uiColor { if let color = model.onTintColor?.uiColor {
containerTintColor?.on = color containerTintColor?.on = color
} }

View File

@ -12,11 +12,12 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
public static var identifier: String = "toggle" public static var identifier: String = "toggle"
public var backgroundColor: Color? public var backgroundColor: Color?
public var state: Bool = true public var state: Bool = false
public var animated: Bool = true public var animated: Bool = true
public var enabled: Bool = true public var enabled: Bool = true
public var action: ActionModelProtocol? public var action: ActionModelProtocol?
public var alternateAction: ActionModelProtocol? public var alternateAction: ActionModelProtocol?
public var accessibilityText: String?
public var fieldKey: String? public var fieldKey: String?
public var groupName: String? = FormValidator.defaultGroupName public var groupName: String? = FormValidator.defaultGroupName
public var baseValue: AnyHashable? public var baseValue: AnyHashable?
@ -25,6 +26,10 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
public var onKnobTintColor: Color? public var onKnobTintColor: Color?
public var offKnobTintColor: Color? public var offKnobTintColor: Color?
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case moleculeName case moleculeName
case state case state
@ -35,22 +40,36 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
case fieldKey case fieldKey
case alternateAction case alternateAction
case groupName case groupName
case accessibilityText
case onTintColor case onTintColor
case offTintColor case offTintColor
case onKnobTintColor case onKnobTintColor
case offKnobTintColor case offKnobTintColor
} }
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
public func formFieldValue() -> AnyHashable? { public func formFieldValue() -> AnyHashable? {
return state return state
} }
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(_ state: Bool) { public init(_ state: Bool) {
self.state = state self.state = state
} }
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
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)
if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) { if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) {
self.state = state self.state = state
} }
@ -71,6 +90,8 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
self.groupName = groupName self.groupName = groupName
} }
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
} }
public func encode(to encoder: Encoder) throws { public func encode(to encoder: Encoder) throws {
@ -88,5 +109,6 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
try container.encodeIfPresent(offKnobTintColor, forKey: .offKnobTintColor) try container.encodeIfPresent(offKnobTintColor, forKey: .offKnobTintColor)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey) try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(groupName, forKey: .groupName) try container.encodeIfPresent(groupName, forKey: .groupName)
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
} }
} }

View File

@ -9,11 +9,18 @@
import Foundation import Foundation
@objcMembers open class ListLeftVariableCheckboxAllTextAndLinks: TableViewCell { @objcMembers open class ListLeftVariableCheckboxAllTextAndLinks: TableViewCell {
public let checkbox = Checkbox(frame: .zero) //--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public let checkbox = Checkbox()
public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero)
public var stack: Stack<StackModel> public var stack: Stack<StackModel>
//--------------------------------------------------
// MARK: - Initializers // MARK: - Initializers
//--------------------------------------------------
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
stack = Stack<StackModel>.createStack(with: [(view: checkbox, model: StackItemModel(horizontalAlignment: .fill)), stack = Stack<StackModel>.createStack(with: [(view: checkbox, model: StackItemModel(horizontalAlignment: .fill)),
(view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))], (view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))],
@ -25,17 +32,25 @@ import Foundation
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
// MARK: - View Lifecycle //--------------------------------------------------
// MARK: - Life Cycle
//--------------------------------------------------
override open func setupView() { override open func setupView() {
super.setupView() super.setupView()
addMolecule(stack) addMolecule(stack)
stack.restack() stack.restack()
} }
// MARK:- MoleculeViewProtocol //--------------------------------------------------
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { // MARK: - MVMCoreUIMoleculeViewProtocol
//--------------------------------------------------
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? ListLeftVariableCheckboxAllTextAndLinksModel else { return}
guard let model = model as? ListLeftVariableCheckboxAllTextAndLinksModel else { return }
checkbox.set(with: model.checkbox, delegateObject, additionalData) checkbox.set(with: model.checkbox, delegateObject, additionalData)
eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData)
} }

View File

@ -9,10 +9,10 @@
import UIKit import UIKit
@objcMembers open class ListLeftVariableRadioButtonAndPaymentMethod: TableViewCell { @objcMembers open class ListLeftVariableRadioButtonAndPaymentMethod: TableViewCell {
//----------------------------------------------------- //-----------------------------------------------------
// MARK: - Outlets // MARK: - Outlets
//----------------------------------------------------- //-----------------------------------------------------
let radioButton = RadioButton(frame: .zero) let radioButton = RadioButton(frame: .zero)
let leftImage = MFLoadImageView(pinnedEdges: .all) let leftImage = MFLoadImageView(pinnedEdges: .all)
let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink() let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink()
@ -21,6 +21,7 @@ import UIKit
//----------------------------------------------------- //-----------------------------------------------------
// MARK: - Initializers // MARK: - Initializers
//----------------------------------------------------- //-----------------------------------------------------
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
stack = Stack<StackModel>.createStack(with: [(view: radioButton, model: StackItemModel(horizontalAlignment: .fill)), stack = Stack<StackModel>.createStack(with: [(view: radioButton, model: StackItemModel(horizontalAlignment: .fill)),
(view: leftImage, model: StackItemModel(horizontalAlignment: .fill)), (view: leftImage, model: StackItemModel(horizontalAlignment: .fill)),
@ -36,6 +37,7 @@ import UIKit
//----------------------------------------------------- //-----------------------------------------------------
// MARK: - View Lifecycle // MARK: - View Lifecycle
//----------------------------------------------------- //-----------------------------------------------------
override open func setupView() { override open func setupView() {
super.setupView() super.setupView()
leftImage.addSizeConstraintsForAspectRatio = true leftImage.addSizeConstraintsForAspectRatio = true
@ -54,6 +56,7 @@ import UIKit
//---------------------------------------------------- //----------------------------------------------------
// MARK: - Molecule // 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) super.set(with: model, delegateObject, additionalData)
guard let model = model as? ListLeftVariableRadioButtonAndPaymentMethodModel else { return} guard let model = model as? ListLeftVariableRadioButtonAndPaymentMethodModel else { return}

View File

@ -9,6 +9,10 @@
import Foundation import Foundation
@objcMembers public class StackItemModel: ContainerModel, StackItemModelProtocol, MoleculeModelProtocol { @objcMembers public class StackItemModel: ContainerModel, StackItemModelProtocol, MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "simpleStackItem" public static var identifier: String = "simpleStackItem"
public var moleculeName: String = StackItemModel.identifier public var moleculeName: String = StackItemModel.identifier
public var backgroundColor: Color? public var backgroundColor: Color?
@ -16,12 +20,18 @@ import Foundation
public var percent: Int? public var percent: Int?
public var gone: Bool = false public var gone: Bool = false
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public convenience init(spacing: CGFloat? = nil, percent: Int? = nil, horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil, gone: Bool? = nil) { public convenience init(spacing: CGFloat? = nil, percent: Int? = nil, horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil, gone: Bool? = nil) {
self.init() self.init()
self.horizontalAlignment = horizontalAlignment self.horizontalAlignment = horizontalAlignment
self.verticalAlignment = verticalAlignment self.verticalAlignment = verticalAlignment
self.spacing = spacing self.spacing = spacing
self.percent = percent self.percent = percent
if let gone = gone { if let gone = gone {
self.gone = gone self.gone = gone
} }

View File

@ -19,7 +19,7 @@ import UIKit
public let body = Label.commonLabelB2(true) public let body = Label.commonLabelB2(true)
public let link = Link() public let link = Link()
var casteModel: EyebrowHeadlineBodyLinkModel? { var castModel: EyebrowHeadlineBodyLinkModel? {
get { return model as? EyebrowHeadlineBodyLinkModel } get { return model as? EyebrowHeadlineBodyLinkModel }
} }
@ -59,10 +59,10 @@ import UIKit
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)
eyebrow.setOptional(with: casteModel?.eyebrow, delegateObject, additionalData) eyebrow.setOptional(with: castModel?.eyebrow, delegateObject, additionalData)
headline.setOptional(with: casteModel?.headline, delegateObject, additionalData) headline.setOptional(with: castModel?.headline, delegateObject, additionalData)
body.setOptional(with: casteModel?.body, delegateObject, additionalData) body.setOptional(with: castModel?.body, delegateObject, additionalData)
link.setOptional(with: casteModel?.link, delegateObject, additionalData) link.setOptional(with: castModel?.link, delegateObject, additionalData)
// Hide labels if neeeded. // Hide labels if neeeded.
stack.stackModel?.molecules[0].gone = !eyebrow.hasText stack.stackModel?.molecules[0].gone = !eyebrow.hasText

View File

@ -9,6 +9,7 @@
import UIKit import UIKit
open class HeadlineBody: View { open class HeadlineBody: View {
let headlineLabel = Label.commonLabelH2(true) let headlineLabel = Label.commonLabelH2(true)
let messageLabel = Label.commonLabelB2(true) let messageLabel = Label.commonLabelB2(true)
var spaceBetweenLabelsConstant = PaddingOne var spaceBetweenLabelsConstant = PaddingOne
@ -72,8 +73,6 @@ open class HeadlineBody: View {
open override func setupView() { open override func setupView() {
super.setupView() super.setupView()
guard subviews.isEmpty else { return }
backgroundColor = .clear backgroundColor = .clear
clipsToBounds = true clipsToBounds = true
@ -81,6 +80,10 @@ open class HeadlineBody: View {
addSubview(view) addSubview(view)
NSLayoutConstraint.constraintPinSubview(toSuperview: view) NSLayoutConstraint.constraintPinSubview(toSuperview: view)
view.isAccessibilityElement = false
view.shouldGroupAccessibilityChildren = true
view.accessibilityElements = [headlineLabel, messageLabel]
view.addSubview(headlineLabel) view.addSubview(headlineLabel)
view.addSubview(messageLabel) view.addSubview(messageLabel)

View File

@ -15,10 +15,11 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
//-------------------------------------------------- //--------------------------------------------------
open var contentView: UIView = MVMCoreUICommonViewsUtility.commonView() open var contentView: UIView = MVMCoreUICommonViewsUtility.commonView()
open var stackItems: [UIView] = []
open var stackModel: T? { open var stackModel: T? {
get { return model as? T } get { return model as? T }
} }
open var stackItems: [UIView] = []
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Helpers // MARK: - Helpers
@ -37,15 +38,21 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
guard let stackModel = stackModel else { return } guard let stackModel = stackModel else { return }
let stackItems = self.stackItems let stackItems = self.stackItems
self.stackItems = [] self.stackItems = []
let lastItemIndex = stackModel.molecules.lastIndex(where: { (item) -> Bool in let lastItemIndex = stackModel.molecules.lastIndex { !$0.gone }
return !item.gone
})
// Adds the views // Adds the views
let totalSpace = getTotalSpace() let totalSpace = getTotalSpace()
for (index, view) in stackItems.enumerated() { for (index, view) in stackItems.enumerated() {
addView(view, stackModel.molecules[index], totalSpacing: totalSpace, lastItem: lastItemIndex == index) addView(view, stackModel.molecules[index], totalSpacing: totalSpace, lastItem: lastItemIndex == index)
} }
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. /// Removes all stack items views from the view.

View File

@ -12,6 +12,7 @@ import UIKit
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
open var model: MoleculeModelProtocol? open var model: MoleculeModelProtocol?
private var initialSetupPerformed = false private var initialSetupPerformed = false
@ -81,7 +82,7 @@ extension Control: AppleGuidelinesProtocol {
// MARK: - MVMCoreViewProtocol // MARK: - MVMCoreViewProtocol
extension Control: MVMCoreViewProtocol { extension Control: MVMCoreViewProtocol {
open func updateView(_ size: CGFloat) {} open func updateView(_ size: CGFloat) { }
/// Will be called only once. /// Will be called only once.
open func setupView() { open func setupView() {

View File

@ -197,10 +197,13 @@ import UIKit
// MARK: - Caret View // MARK: - Caret View
/// Adds the standard mvm style caret to the accessory view /// Adds the standard mvm style caret to the accessory view
@objc public func addCaretViewAccessory() { @objc public func addCaretViewAccessory() {
guard accessoryView == nil else { return } guard accessoryView == nil else { return }
let caret = CaretView(lineWidth: 1) let caret = CaretView(lineWidth: 1)
caret.translatesAutoresizingMaskIntoConstraints = true caret.translatesAutoresizingMaskIntoConstraints = true
caret.isAccessibilityElement = true
caret.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccTabHint")
caret.size = .small(.vertical) caret.size = .small(.vertical)
if let size = caret.size?.dimensions() { if let size = caret.size?.dimensions() {
caret.frame = CGRect(origin: CGPoint.zero, size: size) caret.frame = CGRect(origin: CGPoint.zero, size: size)
@ -246,7 +249,7 @@ import UIKit
// MARK: - MoleculeListCellProtocol // MARK: - MoleculeListCellProtocol
/// For when the separator between cells shows using json and frequency. Default is type: standard, frequency: allExceptTop. /// For when the separator between cells shows using json and frequency. Default is type: standard, frequency: allExceptTop.
public func setLines(with model: LineModel?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?, indexPath: IndexPath) { public func setLines(with model: LineModel?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?, indexPath: IndexPath) {
addSeparatorsIfNeeded() addSeparatorsIfNeeded()
if let model = model { if let model = model {
topSeparatorView?.set(with: model, delegateObject, additionalData) topSeparatorView?.set(with: model, delegateObject, additionalData)
@ -258,7 +261,7 @@ import UIKit
setSeparatorFrequency(model?.frequency ?? .allExceptTop, indexPath: indexPath) setSeparatorFrequency(model?.frequency ?? .allExceptTop, indexPath: indexPath)
} }
public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
//TODO: Use object when handleAction is rewrote to handle action model //TODO: Use object when handleAction is rewrote to handle action model
if let actionMap = self.listItemModel?.action?.toJSON() { if let actionMap = self.listItemModel?.action?.toJSON() {
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)

View File

@ -9,6 +9,10 @@
import Foundation import Foundation
open class ContainerModel: ContainerModelProtocol, Codable { open class ContainerModel: ContainerModelProtocol, Codable {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public var horizontalAlignment: UIStackView.Alignment? public var horizontalAlignment: UIStackView.Alignment?
public var verticalAlignment: UIStackView.Alignment? public var verticalAlignment: UIStackView.Alignment?
public var useHorizontalMargins: Bool? public var useHorizontalMargins: Bool?
@ -17,6 +21,10 @@ open class ContainerModel: ContainerModelProtocol, Codable {
public var topMarginPadding: CGFloat? public var topMarginPadding: CGFloat?
public var bottomMarginPadding: CGFloat? public var bottomMarginPadding: CGFloat?
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case verticalAlignment case verticalAlignment
case horizontalAlignment case horizontalAlignment
@ -26,6 +34,10 @@ open class ContainerModel: ContainerModelProtocol, Codable {
case bottomMarginPadding case bottomMarginPadding
} }
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public init() {} public init() {}
public convenience init(horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil) { public convenience init(horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil) {
@ -34,6 +46,10 @@ open class ContainerModel: ContainerModelProtocol, Codable {
self.verticalAlignment = verticalAlignment self.verticalAlignment = verticalAlignment
} }
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
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)
if let verticalAlignmentString = try typeContainer.decodeIfPresent(String.self, forKey: .verticalAlignment) { if let verticalAlignmentString = try typeContainer.decodeIfPresent(String.self, forKey: .verticalAlignment) {

View File

@ -6,52 +6,73 @@
Copyright © 2017 myverizon. All rights reserved. Copyright © 2017 myverizon. All rights reserved.
*/ */
//// Accessibility // MARK: Accessibility
"AccCloseButton" = "Close"; "AccCloseButton" = "Close";
"swipe_to_select_with_action_hint" = "swipe up or down to select action, then double tap to select."; "swipe_to_select_with_action_hint" = "swipe up or down to select action, then double tap to select.";
// Tab
// MARK: Tab
"AccTab" = ", tab"; "AccTab" = ", tab";
"AccTabHint" = "Double tap to select."; "AccTabHint" = "Double tap to select.";
"AccTabIndex" = ", %ld of %ld"; "AccTabIndex" = ", %ld of %ld";
// top alert
// MARK: Top alert
"toptabbar_tab_selected" = ", tab, Selected"; "toptabbar_tab_selected" = ", tab, Selected";
"AccTopAlertClosed" = "Top alert notification is closed."; "AccTopAlertClosed" = "Top alert notification is closed.";
"top_alert_notification" = "Top alert notification"; "top_alert_notification" = "Top alert notification";
// Textfield
// MARK: Textfield
"textfield_today_string" = "Today"; "textfield_today_string" = "Today";
"textfield_error_message" = "%@.\n The error message.\n %@"; "textfield_error_message" = "%@.\n The error message.\n %@";
"textfield_picker_item" = " picker item"; "textfield_picker_item" = " picker item";
"textfield_regular" = " regular"; "textfield_regular" = " regular";
"textfield_disabled_state" = "disabled"; "textfield_disabled_state" = "disabled";
// MDNTextfield
// MARK: MDNTextfield
"textfield_contacts_barbutton" = "My Contacts"; "textfield_contacts_barbutton" = "My Contacts";
"textfield_phone_format_error_message" = "Invalid phone number format."; "textfield_phone_format_error_message" = "Invalid phone number format.";
// DigitTextfield
// MARK: DigitTextfield
"mfdigittextfield_regular" = " regular"; "mfdigittextfield_regular" = " regular";
// Camera
// MARK: Camera
"AccCameraButton" = "Camera Button"; "AccCameraButton" = "Camera Button";
"AccCameraHint" = "Double tap to launch camera for scanning"; "AccCameraHint" = "Double tap to launch camera for scanning";
// Checkbox
// MARK: Checkbox
"checkbox_action_hint" = "Double tap to change state"; "checkbox_action_hint" = "Double tap to change state";
"checkbox_checked_state" = "Checked"; "checkbox_checked_state" = "Checked";
"checkbox_unchecked_state" = "Unchecked"; "checkbox_unchecked_state" = "Unchecked";
"checkbox_desc_state" = "%@ CheckBox %@"; "checkbox_desc_state" = "%@ CheckBox %@";
// Radio Button
// MARK: Radio Button
"radio_action_hint" = "Double tap to select"; "radio_action_hint" = "Double tap to select";
"radio_selected_state" = "Selected"; "radio_selected_state" = "Selected";
"radio_not_selected_state" = "Not Selected"; "radio_not_selected_state" = "Not Selected";
"radio_desc_state" = "Option"; "radio_desc_state" = "Option";
// Switch
// MARK: Switch / Toggle
"mfswitch_buttonlabel" = "Switch Button"; "mfswitch_buttonlabel" = "Switch Button";
"Toggle_buttonlabel" = "Toggle Button";
"AccOn" = "on"; "AccOn" = "on";
"AccOff" = "off"; "AccOff" = "off";
"AccToggleHint" = "double tap to toggle"; "AccToggleHint" = "double tap to toggle";
// Carousel
// MARK: Carousel
"MVMCoreUIPageControl_currentpage_index" = "page %ld of %ld"; "MVMCoreUIPageControl_currentpage_index" = "page %ld of %ld";
"MVMCoreUIPageControlslides_currentpage_index" = "slide %ld of %ld"; "MVMCoreUIPageControlslides_currentpage_index" = "slide %ld of %ld";
//Styler
// MARK: Styler
"CountDownDay" = " day"; "CountDownDay" = " day";
"CountDownHour" = " hour"; "CountDownHour" = " hour";
"CountDownMin" = " min"; "CountDownMin" = " min";