merge
This commit is contained in:
commit
7f25dd7356
@ -128,6 +128,8 @@
|
||||
8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */; };
|
||||
8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */; };
|
||||
8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */; };
|
||||
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D4687E1242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift */; };
|
||||
8D4687E4242E2DF300802879 /* ListFourColumnDataUsageListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D4687E3242E2DF300802879 /* ListFourColumnDataUsageListItem.swift */; };
|
||||
942C372E241149170066E45E /* NHaasGroteskDSStd-75Bd.otf in Resources */ = {isa = PBXBuildFile; fileRef = 942C372C241149170066E45E /* NHaasGroteskDSStd-75Bd.otf */; };
|
||||
942C372F241149170066E45E /* NHaasGroteskDSStd-55Rg.otf in Resources */ = {isa = PBXBuildFile; fileRef = 942C372D241149170066E45E /* NHaasGroteskDSStd-55Rg.otf */; };
|
||||
942C378C2412F4FA0066E45E /* ModalMoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */; };
|
||||
@ -510,6 +512,8 @@
|
||||
8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaret.swift; sourceTree = "<group>"; };
|
||||
8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretModel.swift; sourceTree = "<group>"; };
|
||||
8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
||||
8D4687E1242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageListItemModel.swift; sourceTree = "<group>"; };
|
||||
8D4687E3242E2DF300802879 /* ListFourColumnDataUsageListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageListItem.swift; sourceTree = "<group>"; };
|
||||
9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = "<group>"; };
|
||||
942C372C241149170066E45E /* NHaasGroteskDSStd-75Bd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NHaasGroteskDSStd-75Bd.otf"; sourceTree = "<group>"; };
|
||||
942C372D241149170066E45E /* NHaasGroteskDSStd-55Rg.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NHaasGroteskDSStd-55Rg.otf"; sourceTree = "<group>"; };
|
||||
@ -1006,6 +1010,15 @@
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D20492F12434CB5F00A5EED6 /* FourColumn */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8D4687E1242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift */,
|
||||
8D4687E3242E2DF300802879 /* ListFourColumnDataUsageListItem.swift */,
|
||||
);
|
||||
path = FourColumn;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D213347423842FE3008E41B3 /* Controllers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1201,6 +1214,7 @@
|
||||
D22B38EA23F4E08B00490EF6 /* List */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D20492F12434CB5F00A5EED6 /* FourColumn */,
|
||||
D22D8396241FDE4700D3DF69 /* TwoColumn */,
|
||||
52267A0523FFE0A900906CBA /* OneColumn */,
|
||||
AA4FC2A323F4F69600E251DB /* RightVariable */,
|
||||
@ -2022,6 +2036,7 @@
|
||||
D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */,
|
||||
01EB368F23609801006832FA /* LabelModel.swift in Sources */,
|
||||
942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */,
|
||||
8D4687E4242E2DF300802879 /* ListFourColumnDataUsageListItem.swift in Sources */,
|
||||
01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */,
|
||||
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */,
|
||||
011B58F023A2AA980085F53C /* ListItemModelProtocol.swift in Sources */,
|
||||
@ -2160,6 +2175,7 @@
|
||||
BB6C6AC924225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift in Sources */,
|
||||
C695A69423C9909000BFB94E /* DoughnutChartModel.swift in Sources */,
|
||||
D29DF32421ED0DA2003B2FB9 /* TextButtonView.m in Sources */,
|
||||
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */,
|
||||
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
|
||||
012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */,
|
||||
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,
|
||||
|
||||
@ -128,9 +128,7 @@ import UIKit
|
||||
|
||||
self.delegateObject = delegateObject
|
||||
isSelected = model.state
|
||||
let radioButtonModel = RadioButtonSelectionHelper.setupForRadioButtonGroup(model,
|
||||
formValidator: delegateObject?.formHolderDelegate?.formValidator)
|
||||
FormValidator.setupValidation(for: radioButtonModel, delegate: delegateObject?.formHolderDelegate)
|
||||
RadioButtonSelectionHelper.setupForRadioButtonGroup(model, self, delegateObject: delegateObject)
|
||||
}
|
||||
|
||||
public override func reset() {
|
||||
|
||||
@ -20,16 +20,20 @@ import UIKit
|
||||
self.fieldKey = fieldKey
|
||||
}
|
||||
|
||||
public static func setupForRadioButtonGroup(_ radioButtonModel: RadioButtonModel, formValidator: FormValidator?) -> RadioButtonSelectionHelper {
|
||||
public static func setupForRadioButtonGroup(_ radioButtonModel: RadioButtonModel, _ radioButton: RadioButton, delegateObject: MVMCoreUIDelegateObject?) {
|
||||
guard let groupName = radioButtonModel.fieldKey,
|
||||
let formValidator = formValidator else {
|
||||
return RadioButtonSelectionHelper(radioButtonModel.fieldKey)
|
||||
let formValidator = delegateObject?.formHolderDelegate?.formValidator else {
|
||||
return
|
||||
}
|
||||
|
||||
let radioButtonSelectionHelper = formValidator.radioButtonsModelByGroup[groupName] ?? RadioButtonSelectionHelper(radioButtonModel.fieldKey)
|
||||
let radioButtonSelectionHelper = formValidator.radioButtonsModelByGroup[groupName] ?? RadioButtonSelectionHelper(radioButtonModel.fieldKey)
|
||||
radioButtonSelectionHelper.fieldGroupName = radioButtonModel.fieldKey
|
||||
formValidator.radioButtonsModelByGroup[groupName] = radioButtonSelectionHelper
|
||||
return radioButtonSelectionHelper
|
||||
|
||||
if radioButtonModel.state {
|
||||
radioButtonSelectionHelper.selectedRadioButton = radioButton
|
||||
}
|
||||
FormValidator.setupValidation(molecule: radioButtonSelectionHelper, delegate: delegateObject?.formHolderDelegate)
|
||||
}
|
||||
|
||||
public func selected(_ radioButton: RadioButton) {
|
||||
|
||||
@ -211,7 +211,7 @@ import UIKit
|
||||
|
||||
let digitBox = DigitBox()
|
||||
digitBox.isAccessibilityElement = true
|
||||
MVMCoreUICommonViewsUtility.addDismissToolbar(digitBox.digitField, delegate: self)
|
||||
digitBox.digitField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: self)
|
||||
digitBox.digitField.delegate = self
|
||||
digitBox.digitBoxDelegate = self
|
||||
return digitBox
|
||||
@ -333,12 +333,10 @@ import UIKit
|
||||
}
|
||||
|
||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
|
||||
|
||||
guard let model = model as? DigitEntryFieldModel else { return }
|
||||
|
||||
numberOfDigits = model.digits
|
||||
|
||||
setAsSecureTextEntry(model.secureEntry)
|
||||
|
||||
for digitBox in digitBoxes {
|
||||
|
||||
@ -116,8 +116,7 @@ import UIKit
|
||||
set (newFeedback) {
|
||||
feedbackLabel.text = newFeedback
|
||||
feedbackLabel.accessibilityElementsHidden = feedbackLabel.text?.isEmpty ?? true
|
||||
entryFieldContainer.refreshUI()
|
||||
delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self)
|
||||
entryFieldContainer.refreshUI(updateMoleculeLayout: true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -49,6 +49,10 @@ import UIKit
|
||||
|
||||
/// Validate when user resigns editing. Default: true
|
||||
public var validateWhenDoneEditing: Bool = true
|
||||
|
||||
public var textEntryFieldModel: TextEntryFieldModel? {
|
||||
return model as? TextEntryFieldModel
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Computed Properties
|
||||
@ -87,7 +91,7 @@ import UIKit
|
||||
get { return textField.text }
|
||||
set {
|
||||
textField.text = newValue
|
||||
(model as? TextEntryFieldModel)?.text = newValue
|
||||
textEntryFieldModel?.text = newValue
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,7 +175,8 @@ import UIKit
|
||||
textField.heightAnchor.constraint(equalToConstant: 24),
|
||||
textField.topAnchor.constraint(equalTo: container.topAnchor, constant: 12),
|
||||
textField.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 16),
|
||||
container.bottomAnchor.constraint(equalTo: textField.bottomAnchor, constant: 12)])
|
||||
container.bottomAnchor.constraint(equalTo: textField.bottomAnchor, constant: 12)
|
||||
])
|
||||
|
||||
textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 16)
|
||||
textFieldTrailingConstraint?.isActive = true
|
||||
|
||||
@ -158,6 +158,7 @@ import MVMCore
|
||||
super.init(frame: frame)
|
||||
|
||||
accessibilityTraits = .button
|
||||
isAccessibilityElement = true
|
||||
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "checkbox_action_hint")
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
@ -198,8 +199,6 @@ import MVMCore
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
|
||||
guard constraints.isEmpty else { return }
|
||||
|
||||
isUserInteractionEnabled = true
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
backgroundColor = .clear
|
||||
@ -390,8 +389,6 @@ import MVMCore
|
||||
widthConstraint?.constant = dimension
|
||||
heightConstraint?.constant = dimension
|
||||
}
|
||||
|
||||
//layoutIfNeeded()
|
||||
}
|
||||
|
||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
@ -130,6 +130,7 @@ public typealias ActionBlock = () -> ()
|
||||
|
||||
required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.init(frame: .zero)
|
||||
setupView()
|
||||
styleB2(true)
|
||||
set(with: model, delegateObject, additionalData)
|
||||
}
|
||||
@ -322,6 +323,7 @@ public typealias ActionBlock = () -> ()
|
||||
text = labelModel.text
|
||||
hero = labelModel.hero
|
||||
Label.setLabel(self, withHTML: labelModel.html)
|
||||
isAccessibilityElement = hasText
|
||||
|
||||
switch labelModel.textAlignment {
|
||||
case .center:
|
||||
@ -428,6 +430,7 @@ public typealias ActionBlock = () -> ()
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
attributedText = attributedString
|
||||
originalAttributedString = attributedText
|
||||
}
|
||||
|
||||
@ -12,6 +12,19 @@ import Foundation
|
||||
@objcMembers public class LabelModel: MoleculeModelProtocol {
|
||||
|
||||
public enum FontStyle: String, Codable {
|
||||
case Title2XLarge
|
||||
case TitleXLarge
|
||||
case BoldTitleLarge
|
||||
case RegularTitleLarge
|
||||
case BoldTitleMedium
|
||||
case RegularTitleMedium
|
||||
case BoldBodyLarge
|
||||
case RegularBodyLarge
|
||||
case BoldBodySmall
|
||||
case RegularBodySmall
|
||||
case BoldMicro
|
||||
case RegularMicro
|
||||
// Legacy
|
||||
case H1
|
||||
case H2
|
||||
case H3
|
||||
|
||||
@ -189,8 +189,11 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
|
||||
public override func setupView() {
|
||||
super.setupView()
|
||||
|
||||
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?.isActive = true
|
||||
@ -214,8 +217,6 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 1)
|
||||
knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1)
|
||||
knobLeadingConstraint?.isActive = true
|
||||
|
||||
accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel")
|
||||
}
|
||||
|
||||
public override func reset() {
|
||||
@ -336,15 +337,13 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
|
||||
// MARK:- MoleculeViewProtocol
|
||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
guard let toggleModel = model as? ToggleModel else {
|
||||
return
|
||||
}
|
||||
|
||||
self.model = model
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
self.delegateObject = delegateObject
|
||||
|
||||
FormValidator.setupValidation(for: toggleModel, delegate: delegateObject?.formHolderDelegate)
|
||||
guard let model = model as? ToggleModel else { return }
|
||||
|
||||
FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate)
|
||||
|
||||
if let color = model.onTintColor?.uiColor {
|
||||
containerTintColor?.on = color
|
||||
}
|
||||
|
||||
@ -12,11 +12,12 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
||||
|
||||
public static var identifier: String = "toggle"
|
||||
public var backgroundColor: Color?
|
||||
public var state: Bool = true
|
||||
public var state: Bool = false
|
||||
public var animated: Bool = true
|
||||
public var enabled: Bool = true
|
||||
public var action: ActionModelProtocol?
|
||||
public var alternateAction: ActionModelProtocol?
|
||||
public var accessibilityText: String?
|
||||
public var onTintColor: Color?
|
||||
public var offTintColor: Color?
|
||||
public var onKnobTintColor: Color?
|
||||
@ -25,7 +26,11 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
||||
public var fieldKey: String?
|
||||
public var groupName: String = FormValidator.defaultGroupName
|
||||
public var baseValue: AnyHashable?
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case state
|
||||
@ -34,6 +39,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
||||
case action
|
||||
case backgroundColor
|
||||
case alternateAction
|
||||
case accessibilityText
|
||||
case onTintColor
|
||||
case offTintColor
|
||||
case onKnobTintColor
|
||||
@ -42,17 +48,30 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
||||
case groupName
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
public func formFieldValue() -> AnyHashable? {
|
||||
return state
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(_ state: Bool) {
|
||||
self.state = state
|
||||
baseValue = state
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) {
|
||||
self.state = state
|
||||
}
|
||||
@ -69,7 +88,8 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
||||
offTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offTintColor)
|
||||
onKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onKnobTintColor)
|
||||
offKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offKnobTintColor)
|
||||
|
||||
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||
|
||||
baseValue = state
|
||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||
@ -84,10 +104,13 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
||||
try container.encodeModelIfPresent(alternateAction, forKey: .alternateAction)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(state, forKey: .state)
|
||||
try container.encode(animated, forKey: .animated)
|
||||
try container.encode(enabled, forKey: .enabled)
|
||||
try container.encodeIfPresent(onTintColor, forKey: .onTintColor)
|
||||
try container.encodeIfPresent(onKnobTintColor, forKey: .onKnobTintColor)
|
||||
try container.encodeIfPresent(onKnobTintColor, forKey: .onKnobTintColor)
|
||||
try container.encodeIfPresent(offKnobTintColor, forKey: .offKnobTintColor)
|
||||
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||
}
|
||||
|
||||
@ -18,18 +18,18 @@ import Foundation
|
||||
}
|
||||
|
||||
/// Registers the model with the model registry and the view with the mapper.
|
||||
func register<M: ModelProtocol, V: MoleculeViewProtocol>(viewClass: V.Type, viewModelClass: M.Type) {
|
||||
public func register<M: ModelProtocol, V: MoleculeViewProtocol>(viewClass: V.Type, viewModelClass: M.Type) {
|
||||
try? ModelRegistry.register(viewModelClass)
|
||||
moleculeMapping.updateValue(viewClass, forKey: viewModelClass.identifier)
|
||||
}
|
||||
|
||||
/// Returns the type of molecule view for the given model
|
||||
func getMoleculeClass(_ model: MoleculeModelProtocol) -> MoleculeViewProtocol.Type? {
|
||||
public func getMoleculeClass(_ model: MoleculeModelProtocol) -> MoleculeViewProtocol.Type? {
|
||||
return moleculeMapping[model.moleculeName]
|
||||
}
|
||||
|
||||
/// Creates a molecule with the given model.
|
||||
func createMolecule(_ model: MoleculeModelProtocol, delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> MoleculeViewProtocol? {
|
||||
public func createMolecule(_ model: MoleculeModelProtocol, delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> MoleculeViewProtocol? {
|
||||
guard let type = moleculeMapping[model.moleculeName] else { return nil }
|
||||
return type.init(model: model, delegateObject, additionalData)
|
||||
}
|
||||
@ -136,6 +136,7 @@ import Foundation
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnCompareChanges.self, viewModelClass: ListTwoColumnCompareChangesModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnPriceDetails.self, viewModelClass: ListTwoColumnPriceDetailsModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnPriceDescription.self, viewModelClass: ListTwoColumnPriceDescriptionModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self)
|
||||
|
||||
// Designed Section Dividers
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self)
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
//
|
||||
// ListFourColumnDataUsageListItem.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Kruthika KP on 27/03/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class ListFourColumnDataUsageListItem: TableViewCell {
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//-----------------------------------------------------
|
||||
var stack: Stack<StackModel>
|
||||
let label1 = Label.commonLabelB2(true)
|
||||
let label2 = Label.commonLabelB2(true)
|
||||
let label3 = Label.commonLabelB2(true)
|
||||
let label4 = Label.commonLabelB2(true)
|
||||
let arrow = Arrow(frame: .zero)
|
||||
let arrowAndLabel2Stack: Stack<StackModel>
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//-----------------------------------------------------
|
||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
arrowAndLabel2Stack = Stack<StackModel>.createStack(with: [(view: arrow, model: StackItemModel(horizontalAlignment: .fill)),
|
||||
(view: label2, model: StackItemModel(horizontalAlignment: .leading))],
|
||||
axis: .horizontal, spacing: 4)
|
||||
label2.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
|
||||
label2.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal)
|
||||
stack = Stack<StackModel>.createStack(with: [(view: label1, model: StackItemModel(percent: 19, horizontalAlignment: .leading)),
|
||||
(view: arrowAndLabel2Stack, model: StackItemModel(percent: 44, horizontalAlignment: .fill)),
|
||||
(view: label3, model: StackItemModel(percent:17,horizontalAlignment: .leading)),
|
||||
(view: label4, model: StackItemModel(percent:20,horizontalAlignment: .leading))],
|
||||
axis: .horizontal,spacing: 8)
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
}
|
||||
|
||||
public required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - View Lifecycle
|
||||
//-----------------------------------------------------
|
||||
override open func setupView() {
|
||||
super.setupView()
|
||||
addMolecule(stack)
|
||||
arrow.pinHeightAndWidth()
|
||||
arrowAndLabel2Stack.restack()
|
||||
stack.restack()
|
||||
}
|
||||
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
guard let model = model as? ListFourColumnDataUsageListItemModel else { return }
|
||||
label1.set(with: model.label1, delegateObject, additionalData)
|
||||
label2.set(with: model.label2, delegateObject, additionalData)
|
||||
label3.set(with: model.label3, delegateObject, additionalData)
|
||||
label4.set(with: model.label4, delegateObject, additionalData)
|
||||
arrow.set(with: model.arrow, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 121
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
label1.styleB2(true)
|
||||
label2.styleB2(true)
|
||||
label3.styleB2(true)
|
||||
label4.styleB2(true)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
//
|
||||
// ListFourColumnDataUsageListItemModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Kruthika KP on 27/03/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public class ListFourColumnDataUsageListItemModel: ListItemModel, MoleculeModelProtocol {
|
||||
public static var identifier: String = "list4C"
|
||||
public var label1: LabelModel
|
||||
public var arrow: ArrowModel
|
||||
public var label2: LabelModel
|
||||
public var label3: LabelModel
|
||||
public var label4: LabelModel
|
||||
|
||||
public init(label1:LabelModel, label2:LabelModel, label3:LabelModel,label4:LabelModel, arrow:ArrowModel) {
|
||||
self.label1 = label1
|
||||
self.label2 = label2
|
||||
self.label3 = label3
|
||||
self.label4 = label4
|
||||
self.arrow = arrow
|
||||
super.init()
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case label1
|
||||
case label2
|
||||
case label3
|
||||
case label4
|
||||
case arrow
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
label1 = try typeContainer.decode(LabelModel.self, forKey: .label1)
|
||||
label2 = try typeContainer.decode(LabelModel.self, forKey: .label2)
|
||||
label3 = try typeContainer.decode(LabelModel.self, forKey: .label3)
|
||||
label4 = try typeContainer.decode(LabelModel.self, forKey: .label4)
|
||||
arrow = try typeContainer.decode(ArrowModel.self, forKey: .arrow)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(label1, forKey: .label1)
|
||||
try container.encode(label2, forKey: .label2)
|
||||
try container.encode(label3, forKey: .label3)
|
||||
try container.encode(label4, forKey: .label4)
|
||||
try container.encode(arrow, forKey: .arrow)
|
||||
}
|
||||
}
|
||||
@ -9,11 +9,18 @@
|
||||
import Foundation
|
||||
|
||||
@objcMembers open class ListLeftVariableCheckboxAllTextAndLinks: TableViewCell {
|
||||
public let checkbox = Checkbox(frame: .zero)
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public let checkbox = Checkbox()
|
||||
public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero)
|
||||
public var stack: Stack<StackModel>
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
stack = Stack<StackModel>.createStack(with: [(view: checkbox, model: StackItemModel(horizontalAlignment: .fill)),
|
||||
(view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))],
|
||||
@ -25,17 +32,25 @@ import Foundation
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
//--------------------------------------------------
|
||||
// MARK: - Life Cycle
|
||||
//--------------------------------------------------
|
||||
|
||||
override open func setupView() {
|
||||
super.setupView()
|
||||
addMolecule(stack)
|
||||
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)
|
||||
guard let model = model as? ListLeftVariableCheckboxAllTextAndLinksModel else { return}
|
||||
|
||||
guard let model = model as? ListLeftVariableCheckboxAllTextAndLinksModel else { return }
|
||||
|
||||
checkbox.set(with: model.checkbox, delegateObject, additionalData)
|
||||
eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
@ -9,10 +9,10 @@
|
||||
import UIKit
|
||||
|
||||
@objcMembers open class ListLeftVariableRadioButtonAndPaymentMethod: TableViewCell {
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//-----------------------------------------------------
|
||||
|
||||
let radioButton = RadioButton(frame: .zero)
|
||||
let leftImage = MFLoadImageView(pinnedEdges: .all)
|
||||
let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink()
|
||||
@ -21,6 +21,7 @@ import UIKit
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//-----------------------------------------------------
|
||||
|
||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
stack = Stack<StackModel>.createStack(with: [(view: radioButton, model: StackItemModel(horizontalAlignment: .fill)),
|
||||
(view: leftImage, model: StackItemModel(horizontalAlignment: .fill)),
|
||||
@ -36,6 +37,7 @@ import UIKit
|
||||
//-----------------------------------------------------
|
||||
// MARK: - View Lifecycle
|
||||
//-----------------------------------------------------
|
||||
|
||||
override open func setupView() {
|
||||
super.setupView()
|
||||
leftImage.addSizeConstraintsForAspectRatio = true
|
||||
@ -54,6 +56,7 @@ import UIKit
|
||||
//----------------------------------------------------
|
||||
// MARK: - Molecule
|
||||
//----------------------------------------------------
|
||||
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
guard let model = model as? ListLeftVariableRadioButtonAndPaymentMethodModel else { return}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
@objcMembers public class DropDownListItemModel: ListItemModel, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
@ -17,6 +18,10 @@ import Foundation
|
||||
public var molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]
|
||||
public var dropDown: ItemDropdownEntryFieldModel
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Defaults to set
|
||||
public override func setDefaults() {
|
||||
super.setDefaults()
|
||||
@ -24,14 +29,25 @@ import Foundation
|
||||
line = LineModel(type: .none)
|
||||
style = "sectionFooter"
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Functions
|
||||
//--------------------------------------------------
|
||||
|
||||
public class func verify(dropdown: ItemDropdownEntryFieldModel, molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]) throws {
|
||||
guard dropdown.options.count == molecules.count else {
|
||||
throw MolecularError.countImbalance("dropdown.options.count is not equal to molecules.count")
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(molecules: [[ListItemModelProtocol & MoleculeModelProtocol]], dropDown: ItemDropdownEntryFieldModel) {
|
||||
public init(molecules: [[ListItemModelProtocol & MoleculeModelProtocol]], dropDown: ItemDropdownEntryFieldModel) throws {
|
||||
self.molecules = molecules
|
||||
self.dropDown = dropDown
|
||||
try Self.verify(dropdown: dropDown, molecules: molecules)
|
||||
super.init()
|
||||
}
|
||||
|
||||
@ -53,6 +69,7 @@ import Foundation
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
molecules = try typeContainer.decodeModels2DIfPresent(codingKey: .molecules) ?? [[]]
|
||||
dropDown = try typeContainer.decode(ItemDropdownEntryFieldModel.self, forKey: .dropDown)
|
||||
try Self.verify(dropdown: dropDown, molecules: molecules)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ import UIKit
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
guard let moleculeModel = (model as? MoleculeContainerModel)?.molecule,
|
||||
guard let moleculeModel = (model as? MoleculeListItemModel)?.molecule,
|
||||
let classType = MoleculeObjectMapping.shared()?.getMoleculeClass(moleculeModel),
|
||||
let height = classType.estimatedHeight(with: moleculeModel, delegateObject)
|
||||
else { return 80 }
|
||||
|
||||
@ -9,6 +9,10 @@
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class StackItemModel: ContainerModel, StackItemModelProtocol, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "simpleStackItem"
|
||||
public var moleculeName: String = StackItemModel.identifier
|
||||
public var backgroundColor: Color?
|
||||
@ -16,12 +20,18 @@ import Foundation
|
||||
public var percent: Int?
|
||||
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) {
|
||||
self.init()
|
||||
|
||||
self.horizontalAlignment = horizontalAlignment
|
||||
self.verticalAlignment = verticalAlignment
|
||||
self.spacing = spacing
|
||||
self.percent = percent
|
||||
|
||||
if let gone = gone {
|
||||
self.gone = gone
|
||||
}
|
||||
|
||||
@ -19,4 +19,26 @@ public class LabelToggleModel: MoleculeModelProtocol {
|
||||
self.label = label
|
||||
self.toggle = toggle
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case label
|
||||
case toggle
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey:.backgroundColor)
|
||||
label = try typeContainer.decode(LabelModel.self, forKey:.label)
|
||||
toggle = try typeContainer.decode(ToggleModel.self, forKey:.toggle)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encode(label, forKey: .label)
|
||||
try container.encode(toggle, forKey: .toggle)
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ import UIKit
|
||||
public let body = Label.commonLabelB2(true)
|
||||
public let link = Link()
|
||||
|
||||
var casteModel: EyebrowHeadlineBodyLinkModel? {
|
||||
var castModel: EyebrowHeadlineBodyLinkModel? {
|
||||
get { return model as? EyebrowHeadlineBodyLinkModel }
|
||||
}
|
||||
|
||||
@ -59,10 +59,10 @@ import UIKit
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
|
||||
eyebrow.setOptional(with: casteModel?.eyebrow, delegateObject, additionalData)
|
||||
headline.setOptional(with: casteModel?.headline, delegateObject, additionalData)
|
||||
body.setOptional(with: casteModel?.body, delegateObject, additionalData)
|
||||
link.setOptional(with: casteModel?.link, delegateObject, additionalData)
|
||||
eyebrow.setOptional(with: castModel?.eyebrow, delegateObject, additionalData)
|
||||
headline.setOptional(with: castModel?.headline, delegateObject, additionalData)
|
||||
body.setOptional(with: castModel?.body, delegateObject, additionalData)
|
||||
link.setOptional(with: castModel?.link, delegateObject, additionalData)
|
||||
|
||||
// Hide labels if neeeded.
|
||||
stack.stackModel?.molecules[0].gone = !eyebrow.hasText
|
||||
|
||||
@ -9,9 +9,10 @@
|
||||
import UIKit
|
||||
|
||||
open class HeadlineBody: View {
|
||||
|
||||
let headlineLabel = Label.commonLabelH2(true)
|
||||
let messageLabel = Label.commonLabelB2(true)
|
||||
var spaceBetweenLabelsConstant = PaddingTwo
|
||||
var spaceBetweenLabelsConstant = PaddingOne
|
||||
var spaceBetweenLabels: NSLayoutConstraint?
|
||||
var leftConstraintTitle: NSLayoutConstraint?
|
||||
var rightConstraintTitle: NSLayoutConstraint?
|
||||
@ -71,8 +72,6 @@ open class HeadlineBody: View {
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
|
||||
guard subviews.isEmpty else { return }
|
||||
|
||||
backgroundColor = .clear
|
||||
clipsToBounds = true
|
||||
@ -81,6 +80,10 @@ open class HeadlineBody: View {
|
||||
addSubview(view)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: view)
|
||||
|
||||
view.isAccessibilityElement = false
|
||||
view.shouldGroupAccessibilityChildren = true
|
||||
view.accessibilityElements = [headlineLabel, messageLabel]
|
||||
|
||||
view.addSubview(headlineLabel)
|
||||
view.addSubview(messageLabel)
|
||||
|
||||
|
||||
@ -28,11 +28,11 @@ open class Carousel: View {
|
||||
/// The number of pages that there are. Used for the page control and for calculations. Should not include the looping dummy cells. Be sure to set this if subclassing and not using the molecules.
|
||||
open var numberOfPages = 0
|
||||
|
||||
/// The json for the molecules.
|
||||
/// The models for the molecules.
|
||||
var molecules: [MoleculeModelProtocol]?
|
||||
|
||||
/// The horizontal alignment of the cell in the collection view. Only noticeable if the itemWidthPercent is less than 100%.
|
||||
var itemAlignment = UICollectionView.ScrollPosition.left
|
||||
public var itemAlignment = UICollectionView.ScrollPosition.left
|
||||
|
||||
/// From 0-1. The item width as a percent of the carousel width.
|
||||
public var itemWidthPercent: Float = 1
|
||||
|
||||
@ -15,10 +15,11 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
|
||||
//--------------------------------------------------
|
||||
|
||||
open var contentView: UIView = MVMCoreUICommonViewsUtility.commonView()
|
||||
open var stackItems: [UIView] = []
|
||||
|
||||
open var stackModel: T? {
|
||||
get { return model as? T }
|
||||
}
|
||||
open var stackItems: [UIView] = []
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Helpers
|
||||
@ -37,15 +38,21 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
|
||||
guard let stackModel = stackModel else { return }
|
||||
let stackItems = self.stackItems
|
||||
self.stackItems = []
|
||||
let lastItemIndex = stackModel.molecules.lastIndex(where: { (item) -> Bool in
|
||||
return !item.gone
|
||||
})
|
||||
let lastItemIndex = stackModel.molecules.lastIndex { !$0.gone }
|
||||
|
||||
// Adds the views
|
||||
let totalSpace = getTotalSpace()
|
||||
for (index, view) in stackItems.enumerated() {
|
||||
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.
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
import Foundation
|
||||
|
||||
|
||||
public enum MolecularError: Swift.Error {
|
||||
case error(String)
|
||||
case countImbalance(String)
|
||||
}
|
||||
|
||||
|
||||
public protocol MoleculeModelProtocol: ModelProtocol {
|
||||
var moleculeName: String { get }
|
||||
var backgroundColor: Color? { get set }
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
//
|
||||
// PageModelProtocol.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 1/9/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol PageModelProtocol {
|
||||
var pageType: String { get set }
|
||||
var screenHeading: String? { get set }
|
||||
<<<<<<< HEAD
|
||||
var navigationItem: NavigationItemModelProtocol? { get set }
|
||||
=======
|
||||
var isAtomicTabs: Bool? { get set }
|
||||
var navigationItem: (NavigationItemModelProtocol & MoleculeModelProtocol)? { get set }
|
||||
>>>>>>> 18f86575e604bb7b53b6bdac4fc677951979031f
|
||||
}
|
||||
@ -20,7 +20,6 @@ public extension TemplateProtocol where Self: ViewController {
|
||||
let data = try JSONSerialization.data(withJSONObject: pageJSON)
|
||||
let decoder = JSONDecoder()
|
||||
let templateModel = try decoder.decode(TemplateModel.self, from: data)
|
||||
print(templateModel.toJSONString() ?? "")
|
||||
self.templateModel = templateModel
|
||||
self.pageModel = templateModel as? MVMControllerModelProtocol
|
||||
}
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
//
|
||||
// ModalMoleculeListTemplate.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Ryan on 3/6/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
open class ModalMoleculeListTemplate: MoleculeListTemplate {
|
||||
|
||||
<<<<<<< HEAD
|
||||
override open func handleNewData() {
|
||||
MVMCoreUICommonViewsUtility.addCloseButton(to: view, action: {[weak self] _ in
|
||||
if let _ = self {
|
||||
MVMCoreNavigationHandler.shared()?.removeCurrentViewController()
|
||||
}
|
||||
=======
|
||||
public var closeButton: MFCustomButton?
|
||||
|
||||
override open func newDataBuildScreen() {
|
||||
super.newDataBuildScreen()
|
||||
closeButton = MVMCoreUICommonViewsUtility.addCloseButton(to: view, action: { [weak self] _ in
|
||||
self?.dismiss()
|
||||
>>>>>>> develop
|
||||
}, verticalCentered: false)
|
||||
super.handleNewData()
|
||||
}
|
||||
}
|
||||
@ -1,58 +0,0 @@
|
||||
//
|
||||
// StackPageTemplate.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Suresh, Kamlesh on 11/22/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
@objcMembers public class StackPageTemplateModel: TemplateModel {
|
||||
public override class var identifier: String {
|
||||
return "stack"
|
||||
}
|
||||
|
||||
public var header: MoleculeModelProtocol?
|
||||
public var moleculeStack: MoleculeStackModel
|
||||
public var footer: MoleculeModelProtocol?
|
||||
|
||||
public init(pageType: String, moleculeStack: MoleculeStackModel) {
|
||||
self.moleculeStack = moleculeStack
|
||||
super.init(pageType: pageType)
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
case pageType
|
||||
case template
|
||||
case screenHeading
|
||||
>>>>>>> develop
|
||||
case header
|
||||
case footer
|
||||
case stack
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
moleculeStack = try typeContainer.decode(MoleculeStackModel.self, forKey: .stack)
|
||||
header = try typeContainer.decodeModelIfPresent(codingKey: .header)
|
||||
footer = try typeContainer.decodeModelIfPresent(codingKey: .footer)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
try container.encode(pageType, forKey: .pageType)
|
||||
try container.encode(template, forKey: .template)
|
||||
>>>>>>> develop
|
||||
try container.encode(moleculeStack, forKey: .stack)
|
||||
try container.encodeModelIfPresent(header, forKey: .header)
|
||||
try container.encodeModelIfPresent(footer, forKey: .footer)
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,7 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
open var model: MoleculeModelProtocol?
|
||||
|
||||
private var initialSetupPerformed = false
|
||||
@ -81,7 +82,7 @@ extension Control: AppleGuidelinesProtocol {
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
extension Control: MVMCoreViewProtocol {
|
||||
|
||||
open func updateView(_ size: CGFloat) {}
|
||||
open func updateView(_ size: CGFloat) { }
|
||||
|
||||
/// Will be called only once.
|
||||
open func setupView() {
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
@objcMembers open class TableViewCell: UITableViewCell, MoleculeViewProtocol, MoleculeListCellProtocol {
|
||||
@objcMembers open class TableViewCell: UITableViewCell, MoleculeViewProtocol, MoleculeListCellProtocol, MVMCoreViewProtocol {
|
||||
|
||||
open var molecule: MoleculeViewProtocol?
|
||||
open var listItemModel: ListItemModelProtocol?
|
||||
@ -197,10 +197,13 @@ import UIKit
|
||||
// MARK: - Caret View
|
||||
/// Adds the standard mvm style caret to the accessory view
|
||||
@objc public func addCaretViewAccessory() {
|
||||
|
||||
guard accessoryView == nil else { return }
|
||||
|
||||
let caret = CaretView(lineWidth: 1)
|
||||
caret.translatesAutoresizingMaskIntoConstraints = true
|
||||
caret.isAccessibilityElement = true
|
||||
caret.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccTabHint")
|
||||
caret.size = .small(.vertical)
|
||||
if let size = caret.size?.dimensions() {
|
||||
caret.frame = CGRect(origin: CGPoint.zero, size: size)
|
||||
@ -246,7 +249,7 @@ import UIKit
|
||||
|
||||
// MARK: - MoleculeListCellProtocol
|
||||
/// 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()
|
||||
if let model = model {
|
||||
topSeparatorView?.set(with: model, delegateObject, additionalData)
|
||||
@ -258,7 +261,7 @@ import UIKit
|
||||
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
|
||||
if let actionMap = self.listItemModel?.action?.toJSON() {
|
||||
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||
|
||||
@ -33,7 +33,7 @@ import UIKit
|
||||
|
||||
/// Checks if the screen width has changed
|
||||
open func screenSizeChanged() -> Bool {
|
||||
return MVMCoreGetterUtility.cgfequalwiththreshold(previousScreenSize.width, view.bounds.size.width, 0.1)
|
||||
return !MVMCoreGetterUtility.cgfequalwiththreshold(previousScreenSize.width, view.bounds.size.width, 0.1)
|
||||
}
|
||||
|
||||
// MARK: - Response handling
|
||||
@ -276,17 +276,18 @@ import UIKit
|
||||
|
||||
open override func viewDidLayoutSubviews() {
|
||||
// Add to fix a constraint bug where the width is zero and things get messed up.
|
||||
guard isViewLoaded,
|
||||
view.bounds.width > 1 else {
|
||||
super.viewDidLayoutSubviews()
|
||||
return
|
||||
guard isViewLoaded, view.bounds.width > 1 else {
|
||||
super.viewDidLayoutSubviews()
|
||||
return
|
||||
}
|
||||
|
||||
if needsUpdateUI || screenSizeChanged() {
|
||||
updateViews()
|
||||
needsUpdateUI = false
|
||||
}
|
||||
|
||||
previousScreenSize = view.bounds.size;
|
||||
|
||||
|
||||
super.viewDidLayoutSubviews()
|
||||
}
|
||||
|
||||
|
||||
@ -8,13 +8,15 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
extension UIStackView: MoleculeViewProtocol {
|
||||
extension UIStackView: MVMCoreViewProtocol {
|
||||
public func updateView(_ size: CGFloat) {
|
||||
for view in arrangedSubviews {
|
||||
(view as? MVMCoreViewProtocol)?.updateView(size)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension UIStackView: MoleculeViewProtocol {
|
||||
public func reset() {
|
||||
for view in arrangedSubviews {
|
||||
(view as? MoleculeViewProtocol)?.reset()
|
||||
|
||||
@ -9,6 +9,10 @@
|
||||
import Foundation
|
||||
|
||||
open class ContainerModel: ContainerModelProtocol, Codable {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public var horizontalAlignment: UIStackView.Alignment?
|
||||
public var verticalAlignment: UIStackView.Alignment?
|
||||
public var useHorizontalMargins: Bool?
|
||||
@ -17,6 +21,10 @@ open class ContainerModel: ContainerModelProtocol, Codable {
|
||||
public var topMarginPadding: CGFloat?
|
||||
public var bottomMarginPadding: CGFloat?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case verticalAlignment
|
||||
case horizontalAlignment
|
||||
@ -26,6 +34,10 @@ open class ContainerModel: ContainerModelProtocol, Codable {
|
||||
case bottomMarginPadding
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public init() {}
|
||||
|
||||
public convenience init(horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil) {
|
||||
@ -33,6 +45,10 @@ open class ContainerModel: ContainerModelProtocol, Codable {
|
||||
self.horizontalAlignment = horizontalAlignment
|
||||
self.verticalAlignment = verticalAlignment
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
@ -260,13 +260,21 @@ import UIKit
|
||||
refreshUI(bottomBarSize: 1)
|
||||
}
|
||||
|
||||
open func refreshUI(bottomBarSize: CGFloat? = nil) {
|
||||
open func refreshUI(bottomBarSize: CGFloat? = nil, updateMoleculeLayout: Bool = false) {
|
||||
|
||||
if !disableAllBorders {
|
||||
let size: CGFloat = bottomBarSize ?? (showError ? 4 : 1)
|
||||
var heightChanged = false
|
||||
|
||||
if let bottomHeight = bottomBar?.bounds.height {
|
||||
heightChanged = size != bottomHeight
|
||||
}
|
||||
bottomBar?.frame = CGRect(x: 0, y: bounds.height - size, width: bounds.width, height: size)
|
||||
|
||||
delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self)
|
||||
if updateMoleculeLayout || heightChanged {
|
||||
delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self)
|
||||
}
|
||||
|
||||
setNeedsDisplay()
|
||||
layoutIfNeeded()
|
||||
}
|
||||
|
||||
@ -30,6 +30,11 @@ import UIKit
|
||||
primaryButton?.isEnabled = enabled
|
||||
}
|
||||
|
||||
public init(withJSON json: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) {
|
||||
super.init(frame: .zero)
|
||||
setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
@ -44,6 +49,11 @@ import UIKit
|
||||
alignCenterHorizontal()
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
primaryButton?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
// MARK: - Constraining
|
||||
open override func copyBackgroundColor() -> Bool {
|
||||
return true
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#import <MVMCoreUI/MFCustomButton.h>
|
||||
#import <MVMCoreUI/MFTextField.h>
|
||||
#import <MVMCoreUI/MFView.h>
|
||||
@class MVMCoreUIDelegateObject;
|
||||
|
||||
typedef enum : NSUInteger {
|
||||
PrimaryButtonTypeRed,
|
||||
@ -117,6 +118,9 @@ static CGFloat const PrimaryButtonSmallHeight = 30.0;
|
||||
- (void)resetButtonType:(PrimaryButtonType)type small:(BOOL)isSmall bordered:(BOOL)bordered;
|
||||
- (void)resetButtonType:(PrimaryButtonType)type tiny:(BOOL)isTiny bordered:(BOOL)bordered;
|
||||
|
||||
// Convenience setter for common keys
|
||||
- (void)setWithJSON:(nullable NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData;
|
||||
|
||||
#pragma mark - Handling Validations
|
||||
|
||||
// Sets the enabled property depending on the validity checks
|
||||
|
||||
@ -655,6 +655,47 @@
|
||||
return button;
|
||||
}
|
||||
|
||||
- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
|
||||
self.primaryButtonType = PrimaryButtonTypeCustom;
|
||||
NSString *style = [json string:@"style"];
|
||||
if ([style isEqualToString:@"primary"]) {
|
||||
[self setAsStandardCustom];
|
||||
} else if ([style isEqualToString:@"secondary"]) {
|
||||
[self setAsSecondaryCustom];
|
||||
}
|
||||
|
||||
NSString *color = [json string:@"fillColor"];
|
||||
if (color) {
|
||||
self.fillColor = [UIColor mfGetColorForHex:color];
|
||||
}
|
||||
if ((color = [json string:KeyTextColor])) {
|
||||
self.textColor = [UIColor mfGetColorForHex:color];
|
||||
}
|
||||
if ((color = [json string:@"borderColor"])) {
|
||||
self.borderColor = [UIColor mfGetColorForHex:color];
|
||||
}
|
||||
_bordered = self.borderColor != nil;
|
||||
if ((color = [json string:@"disabledFillColor"])) {
|
||||
self.disabledFillColor = [UIColor mfGetColorForHex:color];
|
||||
}
|
||||
if ((color = [json string:@"disabledTextColor"])) {
|
||||
self.disabledTextColor = [UIColor mfGetColorForHex:color];
|
||||
}
|
||||
if ((color = [json string:@"disabledBorderColor"])) {
|
||||
self.disabledBorderColor = [UIColor mfGetColorForHex:color];
|
||||
}
|
||||
|
||||
NSString *size = [json string:@"size"];
|
||||
if ([size isEqualToString:@"small"]) {
|
||||
[self setAsSmallButton:YES];
|
||||
} else if ([size isEqualToString:@"tiny"]) {
|
||||
[self setAsTiny:YES];
|
||||
} else {
|
||||
[self setAsSmallButton:NO];
|
||||
}
|
||||
[self setWithActionMap:json delegateObject:delegateObject additionalData:additionalData];
|
||||
}
|
||||
|
||||
#pragma mark - Constraining Protocol
|
||||
|
||||
- (UIStackViewAlignment)horizontalAlignment {
|
||||
|
||||
@ -6,52 +6,73 @@
|
||||
Copyright © 2017 myverizon. All rights reserved.
|
||||
*/
|
||||
|
||||
//// Accessibility
|
||||
// MARK: Accessibility
|
||||
"AccCloseButton" = "Close";
|
||||
"swipe_to_select_with_action_hint" = "swipe up or down to select action, then double tap to select.";
|
||||
// Tab
|
||||
|
||||
|
||||
// MARK: Tab
|
||||
"AccTab" = ", tab";
|
||||
"AccTabHint" = "Double tap to select.";
|
||||
"AccTabIndex" = ", %ld of %ld";
|
||||
// top alert
|
||||
|
||||
|
||||
// MARK: Top alert
|
||||
"toptabbar_tab_selected" = ", tab, Selected";
|
||||
"AccTopAlertClosed" = "Top alert notification is closed.";
|
||||
"top_alert_notification" = "Top alert notification";
|
||||
// Textfield
|
||||
|
||||
|
||||
// MARK: Textfield
|
||||
"textfield_today_string" = "Today";
|
||||
"textfield_error_message" = "%@.\n The error message.\n %@";
|
||||
"textfield_picker_item" = " picker item";
|
||||
"textfield_regular" = " regular";
|
||||
"textfield_disabled_state" = "disabled";
|
||||
// MDNTextfield
|
||||
|
||||
|
||||
// MARK: MDNTextfield
|
||||
"textfield_contacts_barbutton" = "My Contacts";
|
||||
"textfield_phone_format_error_message" = "Invalid phone number format.";
|
||||
// DigitTextfield
|
||||
|
||||
|
||||
// MARK: DigitTextfield
|
||||
"mfdigittextfield_regular" = " regular";
|
||||
// Camera
|
||||
|
||||
|
||||
// MARK: Camera
|
||||
"AccCameraButton" = "Camera Button";
|
||||
"AccCameraHint" = "Double tap to launch camera for scanning";
|
||||
// Checkbox
|
||||
|
||||
|
||||
// MARK: Checkbox
|
||||
"checkbox_action_hint" = "Double tap to change state";
|
||||
"checkbox_checked_state" = "Checked";
|
||||
"checkbox_unchecked_state" = "Unchecked";
|
||||
"checkbox_desc_state" = "%@ CheckBox %@";
|
||||
|
||||
// Radio Button
|
||||
|
||||
// MARK: Radio Button
|
||||
"radio_action_hint" = "Double tap to select";
|
||||
"radio_selected_state" = "Selected";
|
||||
"radio_not_selected_state" = "Not Selected";
|
||||
"radio_desc_state" = "Option";
|
||||
|
||||
// Switch
|
||||
|
||||
// MARK: Switch / Toggle
|
||||
"mfswitch_buttonlabel" = "Switch Button";
|
||||
"Toggle_buttonlabel" = "Toggle Button";
|
||||
"AccOn" = "on";
|
||||
"AccOff" = "off";
|
||||
"AccToggleHint" = "double tap to toggle";
|
||||
// Carousel
|
||||
|
||||
|
||||
// MARK: Carousel
|
||||
"MVMCoreUIPageControl_currentpage_index" = "page %ld of %ld";
|
||||
"MVMCoreUIPageControlslides_currentpage_index" = "slide %ld of %ld";
|
||||
//Styler
|
||||
|
||||
|
||||
// MARK: Styler
|
||||
"CountDownDay" = " day";
|
||||
"CountDownHour" = " hour";
|
||||
"CountDownMin" = " min";
|
||||
|
||||
@ -86,7 +86,7 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed.";
|
||||
|
||||
- (void)pinATopViewController:(UIViewController *)viewController {
|
||||
self.statusBarHeightConstraint.active = NO;
|
||||
id topGuide = viewController.view.safeAreaLayoutGuide.topAnchor;
|
||||
id topGuide = viewController.topLayoutGuide;
|
||||
self.statusBarBottomConstraint = [NSLayoutConstraint constraintWithItem:self.statusBarView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:topGuide attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
|
||||
self.statusBarBottomConstraint.active = YES;
|
||||
}
|
||||
|
||||
@ -9,12 +9,15 @@
|
||||
import Foundation
|
||||
|
||||
public extension MVMCoreUICommonViewsUtility {
|
||||
|
||||
static func getToolbarWithDoneButton(delegate: ObservingTextFieldDelegate) -> UIToolbar {
|
||||
|
||||
let toolbar = self.makeEmptyToolbar()
|
||||
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
||||
let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: #selector(ObservingTextFieldDelegate.dismissFieldInput(sender:)))
|
||||
button.tintColor = .black
|
||||
toolbar.setItems([space, button], animated: false)
|
||||
|
||||
return toolbar
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,15 +260,15 @@ static const CGFloat VertialShadowOffset = 6;
|
||||
UIBezierPath *shadowPath = [UIBezierPath bezierPath];
|
||||
|
||||
//get the variables for frame
|
||||
CGFloat x = 0;
|
||||
CGFloat y = 0;
|
||||
CGFloat x = rect.origin.x;
|
||||
CGFloat y = rect.origin.y;
|
||||
CGFloat width = CGRectGetWidth(rect);
|
||||
CGFloat height = CGRectGetHeight(rect);
|
||||
|
||||
[shadowPath moveToPoint:CGPointMake(x + HorizontalShadowInset, y)];
|
||||
[shadowPath addLineToPoint:CGPointMake(width - HorizontalShadowInset, y)];
|
||||
[shadowPath addLineToPoint:CGPointMake(width - HorizontalShadowInset, height-VertialShadowOffset/2)];
|
||||
[shadowPath addQuadCurveToPoint:CGPointMake(x + HorizontalShadowInset, height - VertialShadowOffset/2) controlPoint:CGPointMake(width/2.f, height - VertialShadowOffset * 1.5)];
|
||||
[shadowPath addLineToPoint:CGPointMake(x + width - HorizontalShadowInset, y)];
|
||||
[shadowPath addLineToPoint:CGPointMake(x + width - HorizontalShadowInset, height-VertialShadowOffset/2)];
|
||||
[shadowPath addQuadCurveToPoint:CGPointMake(x + HorizontalShadowInset, height - VertialShadowOffset/2) controlPoint:CGPointMake((x + width)/2.f, height - VertialShadowOffset * 1.5)];
|
||||
[shadowPath addLineToPoint:CGPointMake(x + HorizontalShadowInset, y)];
|
||||
[shadowPath closePath];
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user