This commit is contained in:
Pfeil, Scott Robert 2020-04-01 16:10:28 -04:00
commit 7f25dd7356
42 changed files with 472 additions and 198 deletions

View File

@ -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 */,

View File

@ -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() {

View File

@ -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) {

View File

@ -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 {

View File

@ -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)
}
}

View File

@ -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

View File

@ -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]?) {

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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}

View File

@ -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)
}

View File

@ -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 }

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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 }

View File

@ -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
}

View File

@ -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
}

View File

@ -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()
}
}

View File

@ -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)
}
}

View File

@ -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() {

View File

@ -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)

View File

@ -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()
}

View File

@ -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()

View File

@ -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)

View File

@ -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()
}

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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";

View File

@ -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;
}

View File

@ -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
}
}

View File

@ -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];