Merge branch 'develop' into feature/designed_external_link
This commit is contained in:
commit
e5648779eb
File diff suppressed because it is too large
Load Diff
17
MVMCoreUI/Actions/ActionCollapseNotificationModel.swift
Normal file
17
MVMCoreUI/Actions/ActionCollapseNotificationModel.swift
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// ActionCollapseNotificationModel.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Ryan on 3/17/20.
|
||||||
|
// Copyright © 2020 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objcMembers public class ActionCollapseNotificationModel: ActionModelProtocol {
|
||||||
|
public static var identifier: String = "collapseNotification"
|
||||||
|
public var actionType: String
|
||||||
|
public var extraParameters: JSONValueDictionary?
|
||||||
|
public var analyticsData: JSONValueDictionary?
|
||||||
|
public var title: String?
|
||||||
|
}
|
||||||
31
MVMCoreUI/Actions/ActionOpenPanelModel.swift
Normal file
31
MVMCoreUI/Actions/ActionOpenPanelModel.swift
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// ActionOpenPanelModel.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Khan, Arshad on 12/02/20.
|
||||||
|
// Copyright © 2020 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class ActionOpenPanelModel: ActionModelProtocol {
|
||||||
|
|
||||||
|
public enum Panel: String, Codable {
|
||||||
|
case left
|
||||||
|
case right
|
||||||
|
case support // Legacy, means left
|
||||||
|
case menu // Legacy, means right.
|
||||||
|
}
|
||||||
|
|
||||||
|
public static var identifier: String = "openPanel"
|
||||||
|
public var actionType: String = ActionOpenPanelModel.identifier
|
||||||
|
public var panel: Panel
|
||||||
|
public var extraParameters: JSONValueDictionary?
|
||||||
|
public var analyticsData: JSONValueDictionary?
|
||||||
|
// Temporary fix till server changes
|
||||||
|
public var title: String?
|
||||||
|
|
||||||
|
public init(panel: Panel) {
|
||||||
|
self.panel = panel
|
||||||
|
}
|
||||||
|
}
|
||||||
23
MVMCoreUI/Actions/ActionTopAlertModel.swift
Normal file
23
MVMCoreUI/Actions/ActionTopAlertModel.swift
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// ActionTopAlertModel.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Suresh, Kamlesh on 12/16/19.
|
||||||
|
// Copyright © 2019 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers public class ActionTopAlertModel: ActionModelProtocol {
|
||||||
|
public static var identifier: String = "topAlert"
|
||||||
|
public var actionType: String = ActionTopAlertModel.identifier
|
||||||
|
public var pageType: String
|
||||||
|
public var extraParameters: JSONValueDictionary?
|
||||||
|
public var analyticsData: JSONValueDictionary?
|
||||||
|
// Temporary fix till server changes
|
||||||
|
public var title: String?
|
||||||
|
|
||||||
|
public init(pageType: String) {
|
||||||
|
self.pageType = pageType
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,7 +18,8 @@ public enum ButtonSize: String, Codable {
|
|||||||
case tiny
|
case tiny
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
|
public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormActionFieldProtocol {
|
||||||
|
|
||||||
public static var identifier: String = "button"
|
public static var identifier: String = "button"
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var title: String
|
public var title: String
|
||||||
@ -32,9 +33,15 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
|
|||||||
public var disabledFillColor: Color?
|
public var disabledFillColor: Color?
|
||||||
public var disabledTextColor: Color?
|
public var disabledTextColor: Color?
|
||||||
public var disabledBorderColor: Color?
|
public var disabledBorderColor: Color?
|
||||||
public var required: Bool?
|
public var groupName: String? = FormValidator.defaultGroupName
|
||||||
public var requiredGroups: [String]?
|
|
||||||
|
public func updateEnable(_ enabled: Bool) {
|
||||||
|
self.enabled = enabled
|
||||||
|
updateUI?()
|
||||||
|
}
|
||||||
|
|
||||||
|
public var updateUI: (() -> Void)?
|
||||||
|
|
||||||
init(with title: String, action: ActionModelProtocol) {
|
init(with title: String, action: ActionModelProtocol) {
|
||||||
self.title = title
|
self.title = title
|
||||||
self.action = action
|
self.action = action
|
||||||
@ -66,8 +73,7 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
|
|||||||
case disabledFillColor
|
case disabledFillColor
|
||||||
case disabledTextColor
|
case disabledTextColor
|
||||||
case disabledBorderColor
|
case disabledBorderColor
|
||||||
case required
|
case groupName
|
||||||
case requiredGroups
|
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
@ -76,8 +82,9 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
|
|||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
title = try typeContainer.decode(String.self, forKey: .title)
|
title = try typeContainer.decode(String.self, forKey: .title)
|
||||||
action = try typeContainer.decodeModel(codingKey: .action)
|
action = try typeContainer.decodeModel(codingKey: .action)
|
||||||
required = try typeContainer.decodeIfPresent(Bool.self, forKey: .required)
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
requiredGroups = try typeContainer.decodeIfPresent([String].self, forKey: .requiredGroups)
|
self.groupName = groupName
|
||||||
|
}
|
||||||
if let style = try typeContainer.decodeIfPresent(ButtonStyle.self, forKey: .style) {
|
if let style = try typeContainer.decodeIfPresent(ButtonStyle.self, forKey: .style) {
|
||||||
self.style = style
|
self.style = style
|
||||||
}
|
}
|
||||||
@ -110,7 +117,6 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
|
|||||||
try container.encodeIfPresent(disabledFillColor, forKey: .disabledFillColor)
|
try container.encodeIfPresent(disabledFillColor, forKey: .disabledFillColor)
|
||||||
try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor)
|
try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor)
|
||||||
try container.encodeIfPresent(disabledBorderColor, forKey: .disabledBorderColor)
|
try container.encodeIfPresent(disabledBorderColor, forKey: .disabledBorderColor)
|
||||||
try container.encodeIfPresent(required, forKey: .required)
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
try container.encodeIfPresent(requiredGroups, forKey: .requiredGroups)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -35,6 +35,27 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol {
|
|||||||
|
|
||||||
private var caretSpacingConstraint: NSLayoutConstraint?
|
private var caretSpacingConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
// MARK: - Inits
|
||||||
|
//------------------------------------------------------
|
||||||
|
|
||||||
|
// Default values for view.
|
||||||
|
public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.init(frame: .zero)
|
||||||
|
backgroundColor = .clear
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
setTitleColor(enabledColor, for: .normal)
|
||||||
|
setTitleColor(disabledColor, for: .disabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
}
|
||||||
|
|
||||||
|
public required init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
// MARK: - Lifecycle
|
// MARK: - Lifecycle
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
@ -115,16 +136,6 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol {
|
|||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
// MARK: - Atomization
|
// MARK: - Atomization
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
|
|
||||||
// Default values for view.
|
|
||||||
@objc open func setAsMolecule() {
|
|
||||||
|
|
||||||
backgroundColor = .clear
|
|
||||||
translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
setTitleColor(enabledColor, for: .normal)
|
|
||||||
setTitleColor(disabledColor, for: .disabled)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
guard let caretLinkModel = model as? CaretLinkModel else { return }
|
guard let caretLinkModel = model as? CaretLinkModel else { return }
|
||||||
if let color = caretLinkModel.backgroundColor {
|
if let color = caretLinkModel.backgroundColor {
|
||||||
@ -17,7 +17,7 @@ open class ExternalLink: Link {
|
|||||||
public var exportImageView: UIImageView?
|
public var exportImageView: UIImageView?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - ModelMoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
@ -36,8 +36,15 @@ import UIKit
|
|||||||
context?.strokePath()
|
context?.strokePath()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open override var intrinsicContentSize: CGSize {
|
||||||
|
guard let size = titleLabel?.intrinsicContentSize else {
|
||||||
|
return super.intrinsicContentSize
|
||||||
|
}
|
||||||
|
return CGSize(width: size.width, height: size.height + 2)
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - ModelMoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
@ -81,6 +88,7 @@ extension Link {
|
|||||||
titleLabel?.lineBreakMode = .byTruncatingTail
|
titleLabel?.lineBreakMode = .byTruncatingTail
|
||||||
titleLabel?.textAlignment = .left
|
titleLabel?.textAlignment = .left
|
||||||
contentHorizontalAlignment = .left
|
contentHorizontalAlignment = .left
|
||||||
|
contentVerticalAlignment = .top
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidationEnableDisableProtocol {
|
open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
||||||
// Used to size the button.
|
// Used to size the button.
|
||||||
var size = MVMCoreUIUtility.getWidth()
|
var size = MVMCoreUIUtility.getWidth()
|
||||||
|
|
||||||
@ -118,18 +118,19 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation
|
|||||||
return CGSize(width: max(width, getMinimumWidth()), height: getHeight())
|
return CGSize(width: max(width, getMinimumWidth()), height: getHeight())
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - ModelMoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
// The button will get styled in the enable check in super.
|
// The button will get styled in the enable check in super.
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
|
||||||
guard let model = model as? ButtonModel else { return }
|
guard let model = model as? ButtonModel else { return }
|
||||||
setTitle(model.title, for: .normal)
|
setTitle(model.title, for: .normal)
|
||||||
|
|
||||||
if let required = model.required,
|
model.updateUI = { [weak self] in
|
||||||
required {
|
self?.enableField(model.enabled)
|
||||||
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate)
|
||||||
}
|
}
|
||||||
|
|
||||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
@ -163,17 +164,8 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation
|
|||||||
open func horizontalAlignment() -> UIStackView.Alignment {
|
open func horizontalAlignment() -> UIStackView.Alignment {
|
||||||
return .center
|
return .center
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - FormValidationEnableDisableProtocol
|
|
||||||
public func isValidationRequired() -> Bool {
|
|
||||||
return buttonModel?.required ?? false
|
|
||||||
}
|
|
||||||
|
|
||||||
public func requiredGroups() -> [String]? {
|
|
||||||
return buttonModel?.requiredGroups
|
|
||||||
}
|
|
||||||
|
|
||||||
public func enableField(_ enable: Bool) {
|
public func enableField(_ enable: Bool) {
|
||||||
isEnabled = isValidationRequired() ? enable : true
|
isEnabled = enable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
138
MVMCoreUI/Atomic/Atoms/Buttons/RadioButton.swift
Normal file
138
MVMCoreUI/Atomic/Atoms/Buttons/RadioButton.swift
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
//
|
||||||
|
// RadioButton.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Suresh, Kamlesh on 4/25/19.
|
||||||
|
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objcMembers open class RadioButton: Control {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public var diameter: CGFloat = 30 {
|
||||||
|
didSet {
|
||||||
|
widthConstraint?.constant = diameter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var enabledColor: UIColor = .black
|
||||||
|
public var disabledColor: UIColor = .mfSilver()
|
||||||
|
public var delegateObject: MVMCoreUIDelegateObject?
|
||||||
|
|
||||||
|
public var radioModel: RadioButtonModel? {
|
||||||
|
return model as? RadioButtonModel
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy public var radioGroupName: String? = {
|
||||||
|
[unowned self] in return radioModel?.fieldKey
|
||||||
|
}()
|
||||||
|
|
||||||
|
lazy public var radioButtonSelectionHelper: RadioButtonSelectionHelper? = {
|
||||||
|
if let radioGroupName = radioGroupName,
|
||||||
|
let radioButtonModel = delegateObject?.formHolderDelegate?.formValidator?.radioButtonsModelByGroup[radioGroupName] {
|
||||||
|
return radioButtonModel
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Constraints
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public var widthConstraint: NSLayoutConstraint?
|
||||||
|
public var heightConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Lifecycle
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
open override func draw(_ rect: CGRect) {
|
||||||
|
guard let context = UIGraphicsGetCurrentContext() else { return }
|
||||||
|
|
||||||
|
let color = isEnabled ? enabledColor.cgColor : disabledColor.cgColor
|
||||||
|
layer.cornerRadius = bounds.width * 0.5
|
||||||
|
layer.borderColor = color
|
||||||
|
layer.borderWidth = bounds.width * 0.0333
|
||||||
|
|
||||||
|
if isSelected {
|
||||||
|
// Space around inner circle is 1/5 the size
|
||||||
|
context.addEllipse(in: CGRect(x: bounds.width * 0.2,
|
||||||
|
y: bounds.height * 0.2,
|
||||||
|
width: bounds.width * 0.6,
|
||||||
|
height: bounds.height * 0.6))
|
||||||
|
context.setFillColor(color)
|
||||||
|
context.fillPath()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Methods
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
/// The action performed when tapped.
|
||||||
|
func tapAction() {
|
||||||
|
if let radioButtonModel = radioButtonSelectionHelper {
|
||||||
|
radioButtonModel.selected(self)
|
||||||
|
} else {
|
||||||
|
isSelected = !isSelected
|
||||||
|
}
|
||||||
|
FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||||
|
setNeedsDisplay()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func isValidField() -> Bool {
|
||||||
|
return isSelected
|
||||||
|
}
|
||||||
|
|
||||||
|
public func formFieldName() -> String? {
|
||||||
|
return radioModel?.fieldKey
|
||||||
|
}
|
||||||
|
|
||||||
|
public func formFieldGroupName() -> String? {
|
||||||
|
return radioModel?.fieldKey
|
||||||
|
}
|
||||||
|
|
||||||
|
public func formFieldValue() -> AnyHashable? {
|
||||||
|
return radioModel?.fieldValue
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - MVMViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
|
||||||
|
backgroundColor = .white
|
||||||
|
clipsToBounds = true
|
||||||
|
widthConstraint = widthAnchor.constraint(equalToConstant: 30)
|
||||||
|
widthConstraint?.isActive = true
|
||||||
|
heightConstraint = heightAnchor.constraint(equalTo: widthAnchor, multiplier: 1)
|
||||||
|
heightConstraint?.isActive = true
|
||||||
|
|
||||||
|
addTarget(self, action: #selector(tapAction), for: .touchUpInside)
|
||||||
|
isAccessibilityElement = true
|
||||||
|
accessibilityTraits = .button
|
||||||
|
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "radio_action_hint")
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
|
||||||
|
guard let model = model as? RadioButtonModel else { return }
|
||||||
|
|
||||||
|
self.delegateObject = delegateObject
|
||||||
|
isSelected = model.state
|
||||||
|
RadioButtonSelectionHelper.setupForRadioButtonGroup(model, self, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func reset() {
|
||||||
|
super.reset()
|
||||||
|
backgroundColor = .white
|
||||||
|
}
|
||||||
|
}
|
||||||
89
MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonModel.swift
Normal file
89
MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonModel.swift
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
//
|
||||||
|
// RadioButtonModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Suresh, Kamlesh on 2/26/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import MVMCore
|
||||||
|
|
||||||
|
|
||||||
|
open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public static var identifier: String = "radioButton"
|
||||||
|
public var backgroundColor: Color?
|
||||||
|
public var state: Bool = false
|
||||||
|
public var enabled: Bool = true
|
||||||
|
|
||||||
|
public var baseValue: AnyHashable?
|
||||||
|
public var groupName: String?
|
||||||
|
public var fieldKey: String?
|
||||||
|
public var fieldValue: String?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Keys
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case backgroundColor
|
||||||
|
case state
|
||||||
|
case enabled
|
||||||
|
case fieldKey
|
||||||
|
case fieldValue
|
||||||
|
case groupName
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializer
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public init(_ state: Bool) {
|
||||||
|
self.state = state
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Method
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public func formFieldValue() -> AnyHashable? {
|
||||||
|
return 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
|
||||||
|
}
|
||||||
|
|
||||||
|
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
||||||
|
self.enabled = enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
|
groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName)
|
||||||
|
fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
|
try container.encode(state, forKey: .state)
|
||||||
|
try container.encode(enabled, forKey: .enabled)
|
||||||
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
|
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// RadioButtonModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Suresh, Kamlesh on 5/14/19.
|
||||||
|
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objcMembers public class RadioButtonSelectionHelper: FormFieldProtocol {
|
||||||
|
|
||||||
|
|
||||||
|
public var fieldKey: String?
|
||||||
|
public var groupName: String? = FormValidator.defaultGroupName
|
||||||
|
var selectedRadioButton: RadioButton?
|
||||||
|
private var fieldGroupName: String?
|
||||||
|
public var baseValue: AnyHashable?
|
||||||
|
|
||||||
|
init(_ fieldKey: String?) {
|
||||||
|
self.fieldKey = fieldKey
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func setupForRadioButtonGroup(_ radioButtonModel: RadioButtonModel, _ radioButton: RadioButton, delegateObject: MVMCoreUIDelegateObject?) {
|
||||||
|
guard let groupName = radioButtonModel.fieldKey,
|
||||||
|
let formValidator = delegateObject?.formHolderDelegate?.formValidator else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let radioButtonSelectionHelper = formValidator.radioButtonsModelByGroup[groupName] ?? RadioButtonSelectionHelper(radioButtonModel.fieldKey)
|
||||||
|
radioButtonSelectionHelper.fieldGroupName = radioButtonModel.fieldKey
|
||||||
|
formValidator.radioButtonsModelByGroup[groupName] = radioButtonSelectionHelper
|
||||||
|
|
||||||
|
if radioButtonModel.state {
|
||||||
|
radioButtonSelectionHelper.selectedRadioButton = radioButton
|
||||||
|
}
|
||||||
|
FormValidator.setupValidation(molecule: radioButtonSelectionHelper, delegate: delegateObject?.formHolderDelegate)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func selected(_ radioButton: RadioButton) {
|
||||||
|
selectedRadioButton?.isSelected = false
|
||||||
|
selectedRadioButton = radioButton
|
||||||
|
selectedRadioButton?.isSelected = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - FormValidationFormFieldProtocol
|
||||||
|
extension RadioButtonSelectionHelper {
|
||||||
|
public func formFieldGroupName() -> String? {
|
||||||
|
return selectedRadioButton?.formFieldGroupName() ?? self.fieldGroupName
|
||||||
|
}
|
||||||
|
|
||||||
|
public func formFieldValue() -> AnyHashable? {
|
||||||
|
return selectedRadioButton?.formFieldValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -52,6 +52,10 @@ import UIKit
|
|||||||
fatalError("DropdownEntryField does not support xib.")
|
fatalError("DropdownEntryField does not support xib.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.init(model: model, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Setup
|
// MARK: - Setup
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -77,15 +81,3 @@ import UIKit
|
|||||||
dropDownCaretView.setOptional(with: model.caretView, delegateObject, additionalData)
|
dropDownCaretView.setOptional(with: model.caretView, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
|
||||||
extension BaseDropdownEntryField {
|
|
||||||
|
|
||||||
@objc override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
|
|
||||||
guard let dictionary = json, !dictionary.isEmpty else { return }
|
|
||||||
|
|
||||||
dropDownCaretView.setWithJSON(dictionary, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -58,6 +58,10 @@ import UIKit
|
|||||||
fatalError("DateDropdownEntryField init(coder:) has not been implemented")
|
fatalError("DateDropdownEntryField init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.init(model: model, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -119,17 +123,3 @@ import UIKit
|
|||||||
dateFormat = model.dateFormat
|
dateFormat = model.dateFormat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
|
||||||
extension DateDropdownEntryField {
|
|
||||||
|
|
||||||
@objc override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
|
|
||||||
guard let dictionary = json, !dictionary.isEmpty else { return }
|
|
||||||
|
|
||||||
if let dateFormat = dictionary["dateFormat"] as? String {
|
|
||||||
self.dateFormat = dateFormat
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -193,6 +193,10 @@ import UIKit
|
|||||||
fatalError("DigitEntryField xib has not been implemented")
|
fatalError("DigitEntryField xib has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.init(model: model, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Setup
|
// MARK: - Setup
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -207,7 +211,7 @@ import UIKit
|
|||||||
|
|
||||||
let digitBox = DigitBox()
|
let digitBox = DigitBox()
|
||||||
digitBox.isAccessibilityElement = true
|
digitBox.isAccessibilityElement = true
|
||||||
MVMCoreUICommonViewsUtility.addDismissToolbar(digitBox.digitField, delegate: self)
|
digitBox.digitField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: self)
|
||||||
digitBox.digitField.delegate = self
|
digitBox.digitField.delegate = self
|
||||||
digitBox.digitBoxDelegate = self
|
digitBox.digitBoxDelegate = self
|
||||||
return digitBox
|
return digitBox
|
||||||
@ -329,20 +333,22 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
|
||||||
|
|
||||||
guard let model = model as? DigitEntryFieldModel else { return }
|
guard let model = model as? DigitEntryFieldModel else { return }
|
||||||
|
|
||||||
numberOfDigits = model.digits
|
numberOfDigits = model.digits
|
||||||
|
|
||||||
setAsSecureTextEntry(model.secureEntry)
|
setAsSecureTextEntry(model.secureEntry)
|
||||||
|
|
||||||
for digitBox in digitBoxes {
|
for digitBox in digitBoxes {
|
||||||
MVMCoreUICommonViewsUtility.addDismissToolbar(digitBox.digitField, delegate: delegateObject as? UITextFieldDelegate)
|
digitBox.digitField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: delegateObject?.observingTextFieldDelegate ?? self)
|
||||||
}
|
}
|
||||||
|
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
return 115
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - TextField Delegate
|
// MARK: - TextField Delegate
|
||||||
@ -440,29 +446,3 @@ extension DigitEntryField {
|
|||||||
return proprietorTextDelegate?.textFieldShouldEndEditing?(textField) ?? true
|
return proprietorTextDelegate?.textFieldShouldEndEditing?(textField) ?? true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
|
||||||
extension DigitEntryField {
|
|
||||||
|
|
||||||
@objc open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
|
|
||||||
guard let dictionary = json else { return }
|
|
||||||
|
|
||||||
numberOfDigits = dictionary["digits"] as? Int ?? 4
|
|
||||||
|
|
||||||
if let _ = dictionary["secureEntry"] as? Bool {
|
|
||||||
setAsSecureTextEntry(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !dictionary.isEmpty{
|
|
||||||
for digitBox in digitBoxes {
|
|
||||||
MVMCoreUICommonViewsUtility.addDismissToolbar(digitBox.digitField, delegate: delegateObject as? UITextFieldDelegate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc open override class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
|
||||||
return 115
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -48,8 +48,6 @@ import UIKit
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public var isValid: Bool = false
|
public var isValid: Bool = false
|
||||||
public var fieldKey: String?
|
|
||||||
|
|
||||||
public var errorMessage: String?
|
public var errorMessage: String?
|
||||||
public var standardMessage: String? {
|
public var standardMessage: String? {
|
||||||
didSet {
|
didSet {
|
||||||
@ -118,8 +116,7 @@ import UIKit
|
|||||||
set (newFeedback) {
|
set (newFeedback) {
|
||||||
feedbackLabel.text = newFeedback
|
feedbackLabel.text = newFeedback
|
||||||
feedbackLabel.accessibilityElementsHidden = feedbackLabel.text?.isEmpty ?? true
|
feedbackLabel.accessibilityElementsHidden = feedbackLabel.text?.isEmpty ?? true
|
||||||
entryFieldContainer.refreshUI()
|
entryFieldContainer.refreshUI(updateMoleculeLayout: true)
|
||||||
delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +160,11 @@ import UIKit
|
|||||||
fatalError("EntryField does not support xib.")
|
fatalError("EntryField does not support xib.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.init(frame: .zero)
|
||||||
|
set(with: model, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Lifecycle
|
// MARK: - Lifecycle
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -228,6 +230,9 @@ import UIKit
|
|||||||
entryFieldContainer.updateView(size)
|
entryFieldContainer.updateView(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - MoleculeViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
@objc open override func reset() {
|
@objc open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
|
|
||||||
@ -259,75 +264,13 @@ import UIKit
|
|||||||
} else if let isSelected = model.isSelected{
|
} else if let isSelected = model.isSelected{
|
||||||
self.isSelected = isSelected
|
self.isSelected = isSelected
|
||||||
}
|
}
|
||||||
|
|
||||||
if let fieldKey = model.fieldKey {
|
|
||||||
self.fieldKey = fieldKey
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
extension EntryField {
|
|
||||||
|
|
||||||
@objc override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
self.delegateObject = delegateObject
|
|
||||||
|
|
||||||
guard let dictionary = json, !dictionary.isEmpty else { return }
|
|
||||||
|
|
||||||
entryFieldContainer.setWithJSON(dictionary, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
|
|
||||||
if let titleText = dictionary[KeyTitle] as? String {
|
|
||||||
title = titleText
|
|
||||||
}
|
|
||||||
|
|
||||||
if let disable = dictionary[KeyDisable] as? String, disable.isEqual(StringY) || dictionary.boolForKey(KeyDisable) {
|
|
||||||
isEnabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if let feedback = dictionary["feedback"] as? String {
|
|
||||||
self.standardMessage = feedback
|
|
||||||
}
|
|
||||||
|
|
||||||
if let errMessage = dictionary[KeyErrorMessage] as? String {
|
|
||||||
errorMessage = errMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
if let isLocked = dictionary["isLocked"] as? Bool {
|
|
||||||
self.isLocked = isLocked
|
|
||||||
}
|
|
||||||
|
|
||||||
if let isSelected = dictionary["isSelected"] as? Bool {
|
|
||||||
self.isSelected = isSelected
|
|
||||||
}
|
|
||||||
|
|
||||||
// Key used to send text value to server
|
|
||||||
if let fieldKey = dictionary[KeyFieldKey] as? String {
|
|
||||||
self.fieldKey = fieldKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc open class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
|
||||||
return 115
|
return 115
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Form Validation
|
|
||||||
extension EntryField: FormValidationProtocol {
|
|
||||||
|
|
||||||
@objc public func isValidField() -> Bool {
|
|
||||||
return isValid
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func formFieldName() -> String? {
|
|
||||||
return fieldKey
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func formFieldValue() -> Any? {
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Accessibility
|
// MARK: - Accessibility
|
||||||
extension EntryField {
|
extension EntryField {
|
||||||
|
|
||||||
@ -9,7 +9,8 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class EntryFieldModel: MoleculeModelProtocol {
|
@objcMembers public class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, ValidProtocol {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -26,8 +27,19 @@ import Foundation
|
|||||||
public var isLocked: Bool?
|
public var isLocked: Bool?
|
||||||
public var isSelected: Bool?
|
public var isSelected: Bool?
|
||||||
public var fieldKey: String?
|
public var fieldKey: String?
|
||||||
public var isValid: Bool?
|
public var groupName: String? = FormValidator.defaultGroupName
|
||||||
public var isRequired: Bool?
|
public var text: String?
|
||||||
|
public var baseValue: AnyHashable?
|
||||||
|
|
||||||
|
public var isValid: Bool? {
|
||||||
|
didSet {
|
||||||
|
updateUI?()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public var updateUI: (() -> Void)?
|
||||||
|
public func setValidity(_ isValid: Bool) {
|
||||||
|
self.isValid = isValid
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
@ -45,6 +57,12 @@ import Foundation
|
|||||||
case fieldKey
|
case fieldKey
|
||||||
case isValid
|
case isValid
|
||||||
case isRequired = "required"
|
case isRequired = "required"
|
||||||
|
case text
|
||||||
|
case groupName
|
||||||
|
}
|
||||||
|
|
||||||
|
public func formFieldValue() -> AnyHashable? {
|
||||||
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -62,6 +80,11 @@ import Foundation
|
|||||||
isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .isSelected)
|
isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .isSelected)
|
||||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
isValid = try typeContainer.decodeIfPresent(Bool.self, forKey: .isValid)
|
isValid = try typeContainer.decodeIfPresent(Bool.self, forKey: .isValid)
|
||||||
|
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
||||||
|
|
||||||
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
|
self.groupName = groupName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -76,5 +99,7 @@ import Foundation
|
|||||||
try container.encode(isSelected, forKey: .isSelected)
|
try container.encode(isSelected, forKey: .isSelected)
|
||||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
try container.encodeIfPresent(isValid, forKey: .isValid)
|
try container.encodeIfPresent(isValid, forKey: .isValid)
|
||||||
|
try container.encodeIfPresent(text, forKey: .text)
|
||||||
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,6 +51,10 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
|||||||
fatalError("ItemDropdownEntryField init(coder:) has not been implemented")
|
fatalError("ItemDropdownEntryField init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.init(model: model, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -135,21 +139,6 @@ extension ItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
|
||||||
extension ItemDropdownEntryField {
|
|
||||||
|
|
||||||
@objc override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
|
|
||||||
guard let dictionary = json, !dictionary.isEmpty else { return }
|
|
||||||
|
|
||||||
if let options = dictionary["options"] as? [String] {
|
|
||||||
pickerData = options
|
|
||||||
setPickerDelegates(delegate: self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Accessibility
|
// MARK: - Accessibility
|
||||||
extension ItemDropdownEntryField {
|
extension ItemDropdownEntryField {
|
||||||
|
|
||||||
@ -65,6 +65,10 @@ import MVMCore
|
|||||||
fatalError("MdnEntryField xib not supported.")
|
fatalError("MdnEntryField xib not supported.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.init(model: model, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Setup
|
// MARK: - Setup
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -97,24 +101,24 @@ import MVMCore
|
|||||||
return MVMCoreUIUtility.validateInternationalMDNString(MDN)
|
return MVMCoreUIUtility.validateInternationalMDNString(MDN)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public override func validateTextField() -> Bool {
|
@objc public func validateMDNTextField() -> Bool {
|
||||||
|
|
||||||
guard !shouldValidateMDN, let MDN = mdn, !MDN.isEmpty else {
|
guard !shouldValidateMDN, let MDN = mdn, !MDN.isEmpty else {
|
||||||
isValid = true
|
isValid = true
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
let isValid = hasValidMDN()
|
let isValid = hasValidMDN()
|
||||||
|
|
||||||
if isValid {
|
if isValid {
|
||||||
showError = false
|
showError = false
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
|
errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
|
||||||
showError = true
|
showError = true
|
||||||
UIAccessibility.post(notification: .layoutChanged, argument: textField)
|
UIAccessibility.post(notification: .layoutChanged, argument: textField)
|
||||||
}
|
}
|
||||||
|
|
||||||
return isValid
|
return isValid
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +190,7 @@ import MVMCore
|
|||||||
|
|
||||||
proprietorTextDelegate?.textFieldDidEndEditing?(textField)
|
proprietorTextDelegate?.textFieldDidEndEditing?(textField)
|
||||||
|
|
||||||
if validateTextField() && isNationalMDN {
|
if validateMDNTextField() && isNationalMDN {
|
||||||
textField.text = MVMCoreUIUtility.formatMdn(textField.text)
|
textField.text = MVMCoreUIUtility.formatMdn(textField.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19,7 +19,7 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@objcMembers open class TextEntryField: EntryField, UITextFieldDelegate {
|
@objcMembers open class TextEntryField: EntryField, UITextFieldDelegate, ObservingTextFieldDelegate {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Outlets
|
// MARK: - Outlets
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -44,12 +44,16 @@ import UIKit
|
|||||||
|
|
||||||
private var observingForChange: Bool = false
|
private var observingForChange: Bool = false
|
||||||
|
|
||||||
/// Validate on each entry in the textField. Default: false
|
/// Validate on each entry in the textField. Default: true
|
||||||
public var validateEachCharacter: Bool = false
|
public var validateEachCharacter: Bool = true
|
||||||
|
|
||||||
/// Validate when user resigns editing. Default: true
|
/// Validate when user resigns editing. Default: true
|
||||||
public var validateWhenDoneEditing: Bool = true
|
public var validateWhenDoneEditing: Bool = true
|
||||||
|
|
||||||
|
public var textEntryFieldModel: TextEntryFieldModel? {
|
||||||
|
return model as? TextEntryFieldModel
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Computed Properties
|
// MARK: - Computed Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -87,7 +91,7 @@ import UIKit
|
|||||||
get { return textField.text }
|
get { return textField.text }
|
||||||
set {
|
set {
|
||||||
textField.text = newValue
|
textField.text = newValue
|
||||||
(model as? TextEntryFieldModel)?.text = newValue
|
textEntryFieldModel?.text = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,6 +158,10 @@ import UIKit
|
|||||||
fatalError("TextEntryField does not support xib.")
|
fatalError("TextEntryField does not support xib.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.init(model: model, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Lifecycle
|
// MARK: - Lifecycle
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -167,7 +175,8 @@ import UIKit
|
|||||||
textField.heightAnchor.constraint(equalToConstant: 24),
|
textField.heightAnchor.constraint(equalToConstant: 24),
|
||||||
textField.topAnchor.constraint(equalTo: container.topAnchor, constant: 12),
|
textField.topAnchor.constraint(equalTo: container.topAnchor, constant: 12),
|
||||||
textField.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 16),
|
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 = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 16)
|
||||||
textFieldTrailingConstraint?.isActive = true
|
textFieldTrailingConstraint?.isActive = true
|
||||||
@ -197,9 +206,8 @@ import UIKit
|
|||||||
@objc deinit {
|
@objc deinit {
|
||||||
setBothTextDelegates(to: nil)
|
setBothTextDelegates(to: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
|
@objc public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
|
||||||
|
|
||||||
observingTextFieldDelegate = delegate
|
observingTextFieldDelegate = delegate
|
||||||
uiTextFieldDelegate = delegate
|
uiTextFieldDelegate = delegate
|
||||||
}
|
}
|
||||||
@ -218,62 +226,55 @@ import UIKit
|
|||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
@objc override open func resignFirstResponder() -> Bool {
|
@objc override open func resignFirstResponder() -> Bool {
|
||||||
|
|
||||||
if validateWhenDoneEditing {
|
if validateWhenDoneEditing {
|
||||||
validateTextField()
|
validateTextField()
|
||||||
}
|
}
|
||||||
|
|
||||||
textField.resignFirstResponder()
|
textField.resignFirstResponder()
|
||||||
isSelected = false
|
isSelected = false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Validates the text of the entry field.
|
/// Validates the text of the entry field.
|
||||||
@discardableResult
|
@objc public func validateTextField() {
|
||||||
@objc public func validateTextField() -> Bool {
|
text = textField.text
|
||||||
|
FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||||
isValid = validationBlock?(text) ?? true
|
}
|
||||||
|
|
||||||
if isValid {
|
@objc public func updateValidation(_ isValid: Bool) {
|
||||||
showError = false
|
let previousValidity = self.isValid
|
||||||
observingTextFieldDelegate?.isValid?(textfield: self)
|
self.isValid = isValid
|
||||||
|
|
||||||
} else {
|
if previousValidity && !isValid {
|
||||||
showError = true
|
showError = true
|
||||||
observingTextFieldDelegate?.isInvalid?(textfield: self)
|
observingTextFieldDelegate?.isInvalid?(textfield: self)
|
||||||
|
} else if (!previousValidity && isValid) {
|
||||||
|
showError = false
|
||||||
|
observingTextFieldDelegate?.isValid?(textfield: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
return isValid
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Executes on UITextField.textDidBeginEditingNotification
|
/// Executes on UITextField.textDidBeginEditingNotification
|
||||||
@objc func startEditing() {
|
@objc func startEditing() {
|
||||||
|
|
||||||
isSelected = true
|
isSelected = true
|
||||||
textField.becomeFirstResponder()
|
textField.becomeFirstResponder()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Executes on UITextField.textDidChangeNotification (each character entry)
|
/// Executes on UITextField.textDidChangeNotification (each character entry)
|
||||||
@objc func valueChanged() {
|
@objc func valueChanged() {
|
||||||
|
|
||||||
guard validateEachCharacter else { return }
|
guard validateEachCharacter else { return }
|
||||||
|
isSelected = true
|
||||||
validateTextField()
|
validateTextField()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Executes on UITextField.textDidEndEditingNotification
|
/// Executes on UITextField.textDidEndEditingNotification
|
||||||
@objc func endInputing() {
|
@objc func endInputing() {
|
||||||
|
resignFirstResponder()
|
||||||
if isValid {
|
if isValid {
|
||||||
showError = false
|
showError = false
|
||||||
entryFieldContainer.bottomBar?.backgroundColor = UIColor.black.cgColor
|
entryFieldContainer.bottomBar?.backgroundColor = UIColor.black.cgColor
|
||||||
}
|
}
|
||||||
|
|
||||||
resignFirstResponder()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func dismissFieldInput(_ sender: Any?) {
|
@objc func dismissFieldInput(_ sender: Any?) {
|
||||||
|
|
||||||
resignFirstResponder()
|
resignFirstResponder()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,24 +282,26 @@ import UIKit
|
|||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
|
||||||
guard let model = model as? TextEntryFieldModel else { return }
|
guard let model = model as? TextEntryFieldModel else { return }
|
||||||
|
|
||||||
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
|
model.updateUI = { [weak self] in
|
||||||
|
if self?.isSelected ?? false {
|
||||||
|
self?.updateValidation(model.isValid ?? true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.delegateObject = delegateObject
|
||||||
|
FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate)
|
||||||
textColor.enabled = model.enabledTextColor?.uiColor
|
textColor.enabled = model.enabledTextColor?.uiColor
|
||||||
textColor.disabled = model.disabledTextColor?.uiColor
|
textColor.disabled = model.disabledTextColor?.uiColor
|
||||||
text = model.text
|
text = model.text
|
||||||
placeholder = model.placeholder
|
placeholder = model.placeholder
|
||||||
|
|
||||||
switch model.type {
|
switch model.type {
|
||||||
case "password":
|
case .password:
|
||||||
textField.isSecureTextEntry = true
|
textField.isSecureTextEntry = true
|
||||||
|
case .number:
|
||||||
case "number":
|
|
||||||
textField.keyboardType = .numberPad
|
textField.keyboardType = .numberPad
|
||||||
|
case .email:
|
||||||
case "email":
|
|
||||||
textField.keyboardType = .emailAddress
|
textField.keyboardType = .emailAddress
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -312,74 +315,9 @@ import UIKit
|
|||||||
defaultValidationBlock()
|
defaultValidationBlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
if let formValidationProtocol = delegateObject?.formValidationProtocol {
|
|
||||||
observingTextFieldDelegate = FormValidator.getFormValidatorFor(delegate: formValidationProtocol)
|
|
||||||
}
|
|
||||||
|
|
||||||
uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate
|
uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate
|
||||||
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate)
|
observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate
|
||||||
}
|
textField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: observingTextFieldDelegate ?? self)
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
|
||||||
extension TextEntryField {
|
|
||||||
|
|
||||||
@objc open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
|
|
||||||
guard let delegateObject = delegateObject,
|
|
||||||
let dictionary = json
|
|
||||||
else { return }
|
|
||||||
|
|
||||||
FormValidator.setupValidation(molecule: self, delegate: delegateObject.formValidationProtocol)
|
|
||||||
|
|
||||||
if let enabledTextColorHex = dictionary["enabledTextColor"] as? String {
|
|
||||||
textColor.enabled = UIColor.mfGet(forHex: enabledTextColorHex)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let disabledTextColorHex = dictionary["disabledTextColor"] as? String {
|
|
||||||
textColor.disabled = UIColor.mfGet(forHex: disabledTextColorHex)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let text = dictionary[KeyText] as? String {
|
|
||||||
self.text = text
|
|
||||||
}
|
|
||||||
|
|
||||||
if let placeholder = dictionary[placeholder] as? String {
|
|
||||||
self.placeholder = placeholder
|
|
||||||
}
|
|
||||||
|
|
||||||
switch dictionary.stringForkey(KeyType) {
|
|
||||||
case "password":
|
|
||||||
textField.isSecureTextEntry = true
|
|
||||||
|
|
||||||
case "number":
|
|
||||||
textField.keyboardType = .numberPad
|
|
||||||
|
|
||||||
case "email":
|
|
||||||
textField.keyboardType = .emailAddress
|
|
||||||
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
let regex = dictionary.stringForkey("regex")
|
|
||||||
|
|
||||||
if !regex.isEmpty {
|
|
||||||
validationBlock = { enteredValue in
|
|
||||||
guard let value = enteredValue else { return false }
|
|
||||||
return MVMCoreUIUtility.validate(value, withRegularExpression: regex)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
defaultValidationBlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
if let formValidationProtocol = delegateObject.formValidationProtocol {
|
|
||||||
observingTextFieldDelegate = FormValidator.getFormValidatorFor(delegate: formValidationProtocol)
|
|
||||||
}
|
|
||||||
|
|
||||||
uiTextFieldDelegate = delegateObject.uiTextFieldDelegate
|
|
||||||
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8,6 +8,13 @@
|
|||||||
|
|
||||||
|
|
||||||
@objcMembers public class TextEntryFieldModel: EntryFieldModel {
|
@objcMembers public class TextEntryFieldModel: EntryFieldModel {
|
||||||
|
|
||||||
|
public enum EntryType: String, Codable {
|
||||||
|
case password
|
||||||
|
case number
|
||||||
|
case email
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -16,11 +23,10 @@
|
|||||||
return "textField"
|
return "textField"
|
||||||
}
|
}
|
||||||
|
|
||||||
public var text: String?
|
|
||||||
public var placeholder: String?
|
public var placeholder: String?
|
||||||
public var enabledTextColor: Color?
|
public var enabledTextColor: Color?
|
||||||
public var disabledTextColor: Color?
|
public var disabledTextColor: Color?
|
||||||
public var type: String?
|
public var type: EntryType?
|
||||||
public var regex: String?
|
public var regex: String?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -48,7 +54,7 @@
|
|||||||
placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder)
|
placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder)
|
||||||
enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor)
|
enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor)
|
||||||
disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor)
|
disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor)
|
||||||
type = try typeContainer.decodeIfPresent(String.self, forKey: .type)
|
type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type)
|
||||||
regex = try typeContainer.decodeIfPresent(String.self, forKey: .regex)
|
regex = try typeContainer.decodeIfPresent(String.self, forKey: .regex)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,16 +178,12 @@ open class CaretView: View {
|
|||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
|
|
||||||
// Default values for view.
|
// Default values for view.
|
||||||
@objc open override func setAsMolecule() {
|
public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
|
super.init(frame: .zero)
|
||||||
defaultState()
|
defaultState()
|
||||||
}
|
|
||||||
|
|
||||||
public override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
guard let json = json, let model = try? Self.decodeJSONToModel(json: json, type: CaretViewModel.self) else { return }
|
|
||||||
set(with: model, delegateObject, additionalData)
|
set(with: model, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - MVMCoreMoleculeViewProtocol
|
|
||||||
override public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
override public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
guard let caretModel = model as? CaretViewModel else {
|
guard let caretModel = model as? CaretViewModel else {
|
||||||
@ -126,9 +126,10 @@ import MVMCore
|
|||||||
didSet {
|
didSet {
|
||||||
if !updateSelectionOnly {
|
if !updateSelectionOnly {
|
||||||
layoutIfNeeded()
|
layoutIfNeeded()
|
||||||
|
(model as? CheckboxModel)?.isChecked = isSelected
|
||||||
shapeLayer?.removeAllAnimations()
|
shapeLayer?.removeAllAnimations()
|
||||||
updateCheckboxUI(isSelected: isSelected, isAnimated: isAnimated)
|
updateCheckboxUI(isSelected: isSelected, isAnimated: isAnimated)
|
||||||
FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol)
|
FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||||
updateAccessibilityLabel()
|
updateAccessibilityLabel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,6 +158,7 @@ import MVMCore
|
|||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
|
|
||||||
accessibilityTraits = .button
|
accessibilityTraits = .button
|
||||||
|
isAccessibilityElement = true
|
||||||
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "checkbox_action_hint")
|
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "checkbox_action_hint")
|
||||||
updateAccessibilityLabel()
|
updateAccessibilityLabel()
|
||||||
}
|
}
|
||||||
@ -197,8 +199,6 @@ import MVMCore
|
|||||||
open override func setupView() {
|
open override func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
|
|
||||||
guard constraints.isEmpty else { return }
|
|
||||||
|
|
||||||
isUserInteractionEnabled = true
|
isUserInteractionEnabled = true
|
||||||
translatesAutoresizingMaskIntoConstraints = false
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
@ -381,11 +381,7 @@ import MVMCore
|
|||||||
checkWidth = 2.0
|
checkWidth = 2.0
|
||||||
checkAndBypassAnimations(selected: false)
|
checkAndBypassAnimations(selected: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
open func setAsMolecule() {
|
|
||||||
setupView()
|
|
||||||
}
|
|
||||||
|
|
||||||
public override func updateView(_ size: CGFloat) {
|
public override func updateView(_ size: CGFloat) {
|
||||||
super.updateView(size)
|
super.updateView(size)
|
||||||
|
|
||||||
@ -393,20 +389,13 @@ import MVMCore
|
|||||||
widthConstraint?.constant = dimension
|
widthConstraint?.constant = dimension
|
||||||
heightConstraint?.constant = dimension
|
heightConstraint?.constant = dimension
|
||||||
}
|
}
|
||||||
|
|
||||||
//layoutIfNeeded()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
|
||||||
guard let model = model as? CheckboxModel else { return }
|
guard let model = model as? CheckboxModel else { return }
|
||||||
|
|
||||||
self.delegateObject = delegateObject
|
self.delegateObject = delegateObject
|
||||||
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
|
FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate)
|
||||||
|
|
||||||
groupName = model.groupName
|
|
||||||
fieldValue = model.fieldValue
|
|
||||||
|
|
||||||
if let fieldKey = model.fieldKey {
|
if let fieldKey = model.fieldKey {
|
||||||
self.fieldKey = fieldKey
|
self.fieldKey = fieldKey
|
||||||
@ -440,23 +429,3 @@ import MVMCore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK:- FormValidationProtocol
|
|
||||||
extension Checkbox: FormValidationFormFieldProtocol {
|
|
||||||
|
|
||||||
public func formFieldGroupName() -> String? {
|
|
||||||
return groupName
|
|
||||||
}
|
|
||||||
|
|
||||||
public func isValidField() -> Bool {
|
|
||||||
return (fieldKey != nil) ? isSelected : true
|
|
||||||
}
|
|
||||||
|
|
||||||
public func formFieldName() -> String? {
|
|
||||||
return fieldKey
|
|
||||||
}
|
|
||||||
|
|
||||||
public func formFieldValue() -> Any? {
|
|
||||||
return fieldValue ?? (isSelected ? fieldValue : nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -65,6 +65,14 @@
|
|||||||
alignCheckbox(.center)
|
alignCheckbox(.center)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc override open func updateView(_ size: CGFloat) {
|
||||||
|
super.updateView(size)
|
||||||
|
|
||||||
|
label.updateView(size)
|
||||||
|
checkbox.updateView(size)
|
||||||
|
layoutIfNeeded()
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -115,6 +123,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Atomic
|
||||||
|
//--------------------------------------------------
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
guard let checkBoxWithLabelModel = model as? CheckboxLabelModel else { return }
|
guard let checkBoxWithLabelModel = model as? CheckboxLabelModel else { return }
|
||||||
|
|
||||||
@ -125,23 +136,11 @@
|
|||||||
checkbox.set(with: checkBoxWithLabelModel.checkbox, delegateObject, additionalData)
|
checkbox.set(with: checkBoxWithLabelModel.checkbox, delegateObject, additionalData)
|
||||||
label.set(with: checkBoxWithLabelModel.label, delegateObject, additionalData)
|
label.set(with: checkBoxWithLabelModel.label, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Molecular
|
|
||||||
extension CheckboxLabel {
|
|
||||||
|
|
||||||
open class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
return 200
|
return 200
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc override open func updateView(_ size: CGFloat) {
|
|
||||||
super.updateView(size)
|
|
||||||
|
|
||||||
label.updateView(size)
|
|
||||||
checkbox.updateView(size)
|
|
||||||
layoutIfNeeded()
|
|
||||||
}
|
|
||||||
|
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
|
|
||||||
@ -149,17 +148,4 @@ extension CheckboxLabel {
|
|||||||
checkbox.reset()
|
checkbox.reset()
|
||||||
alignCheckbox(.center)
|
alignCheckbox(.center)
|
||||||
}
|
}
|
||||||
|
|
||||||
override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
|
|
||||||
guard let dictionary = json else { return }
|
|
||||||
|
|
||||||
if let checkboxAlignment = dictionary["checkboxAlignment"] as? String, let position = CheckboxPosition(rawValue: checkboxAlignment) {
|
|
||||||
alignCheckbox(position)
|
|
||||||
}
|
|
||||||
|
|
||||||
checkbox.setWithJSON(dictionary.dictionaryForKey("checkbox"), delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
label.setWithJSON(dictionary.dictionaryForKey("label"), delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -16,8 +16,8 @@ public enum CheckboxPosition: String, Codable {
|
|||||||
|
|
||||||
@objcMembers public class CheckboxLabelModel: MoleculeModelProtocol {
|
@objcMembers public class CheckboxLabelModel: MoleculeModelProtocol {
|
||||||
public static var identifier: String = "checkboxLabel"
|
public static var identifier: String = "checkboxLabel"
|
||||||
|
public var moleculeName: String
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
|
|
||||||
public var checkboxAlignment: CheckboxPosition?
|
public var checkboxAlignment: CheckboxPosition?
|
||||||
public var checkbox: CheckboxModel
|
public var checkbox: CheckboxModel
|
||||||
public var label: LabelModel
|
public var label: LabelModel
|
||||||
@ -8,18 +8,13 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class CheckboxModel: MoleculeModelProtocol {
|
@objcMembers public class CheckboxModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public static var identifier: String = "checkbox"
|
public static var identifier: String = "checkbox"
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
|
|
||||||
public var groupName: String?
|
|
||||||
public var fieldKey: String?
|
|
||||||
public var fieldValue: JSONValue?
|
|
||||||
|
|
||||||
public var isChecked: Bool = false
|
public var isChecked: Bool = false
|
||||||
public var isEnabled: Bool = true
|
public var isEnabled: Bool = true
|
||||||
public var isAnimated: Bool = true
|
public var isAnimated: Bool = true
|
||||||
@ -34,13 +29,18 @@ import Foundation
|
|||||||
public var disabledCheckColor: Color = Color(uiColor: .mvmCoolGray3)
|
public var disabledCheckColor: Color = Color(uiColor: .mvmCoolGray3)
|
||||||
public var action: ActionModelProtocol?
|
public var action: ActionModelProtocol?
|
||||||
|
|
||||||
|
|
||||||
|
public var fieldKey: String?
|
||||||
|
public var fieldValue: JSONValue?
|
||||||
|
public var groupName: String? = FormValidator.defaultGroupName
|
||||||
|
public var baseValue: AnyHashable?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case groupName
|
|
||||||
case fieldKey
|
case fieldKey
|
||||||
case fieldValue
|
case fieldValue
|
||||||
case isChecked = "checked"
|
case isChecked = "checked"
|
||||||
@ -56,17 +56,21 @@ import Foundation
|
|||||||
case disabledCheckColor
|
case disabledCheckColor
|
||||||
case disabledBorderColor
|
case disabledBorderColor
|
||||||
case action
|
case action
|
||||||
|
case groupName
|
||||||
}
|
}
|
||||||
|
|
||||||
init(isChecked: Bool = false) {}
|
init(isChecked: Bool = false) {}
|
||||||
|
|
||||||
|
public func formFieldValue() -> AnyHashable? {
|
||||||
|
return isChecked
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Codec
|
// MARK: - Codec
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName)
|
|
||||||
fieldValue = try typeContainer.decodeIfPresent(JSONValue.self, forKey: .fieldValue)
|
fieldValue = try typeContainer.decodeIfPresent(JSONValue.self, forKey: .fieldValue)
|
||||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) ?? 1
|
borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) ?? 1
|
||||||
@ -82,6 +86,9 @@ import Foundation
|
|||||||
isRound = try typeContainer.decodeIfPresent(Bool.self, forKey: .isRound) ?? false
|
isRound = try typeContainer.decodeIfPresent(Bool.self, forKey: .isRound) ?? false
|
||||||
isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEnabled) ?? true
|
isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEnabled) ?? true
|
||||||
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
|
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
|
||||||
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
|
self.groupName = groupName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -103,5 +110,6 @@ import Foundation
|
|||||||
try container.encodeIfPresent(isRound, forKey: .isRound)
|
try container.encodeIfPresent(isRound, forKey: .isRound)
|
||||||
try container.encodeIfPresent(isEnabled, forKey: .isEnabled)
|
try container.encodeIfPresent(isEnabled, forKey: .isEnabled)
|
||||||
try container.encodeModelIfPresent(action, forKey: .action)
|
try container.encodeModelIfPresent(action, forKey: .action)
|
||||||
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,12 +87,6 @@ open class DashLine: View {
|
|||||||
isHidden = false
|
isHidden = false
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
guard let json = json, let model = try? Self.decodeJSONToModel(json: json, type: DashLineModel.self) else { return }
|
|
||||||
set(with: model, delegateObject, additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: - MVMCoreMoleculeViewProtocol
|
|
||||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
guard let dashLineModel = dashModel else {
|
guard let dashLineModel = dashModel else {
|
||||||
@ -32,11 +32,6 @@ import UIKit
|
|||||||
createGraphCircle(model)
|
createGraphCircle(model)
|
||||||
rotationAnimation(model)
|
rotationAnimation(model)
|
||||||
}
|
}
|
||||||
|
|
||||||
override open func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
guard let json = json, let model = try? Self.decodeJSONToModel(json: json, type: CircleProgressModel.self) else { return }
|
|
||||||
set(with: model, delegateObject, additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
class func getAngle(_ piValue: Double) -> Double {
|
class func getAngle(_ piValue: Double) -> Double {
|
||||||
return piValue / (2.0 * Double.pi) * 360.0
|
return piValue / (2.0 * Double.pi) * 360.0
|
||||||
@ -11,7 +11,7 @@ import Foundation
|
|||||||
@objcMembers public class ImageViewModel: MoleculeModelProtocol {
|
@objcMembers public class ImageViewModel: MoleculeModelProtocol {
|
||||||
public static var identifier: String = "image"
|
public static var identifier: String = "image"
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var moleculeName: String? = ImageViewModel.identifier
|
public var moleculeName: String = ImageViewModel.identifier
|
||||||
public var image: String
|
public var image: String
|
||||||
public var accessibilityText: String?
|
public var accessibilityText: String?
|
||||||
public var fallbackImage: String?
|
public var fallbackImage: String?
|
||||||
@ -12,7 +12,7 @@ import MVMCore
|
|||||||
public typealias ActionBlock = () -> ()
|
public typealias ActionBlock = () -> ()
|
||||||
|
|
||||||
|
|
||||||
@objcMembers open class Label: UILabel, MVMCoreViewProtocol, MVMCoreUIMoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol, MFButtonProtocol, ModelMoleculeViewProtocol {
|
@objcMembers open class Label: UILabel, MVMCoreViewProtocol, MoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol, MFButtonProtocol {
|
||||||
|
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
@ -128,6 +128,13 @@ 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)
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
// MARK: - Factory Functions
|
// MARK: - Factory Functions
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
@ -316,15 +323,13 @@ public typealias ActionBlock = () -> ()
|
|||||||
text = labelModel.text
|
text = labelModel.text
|
||||||
hero = labelModel.hero
|
hero = labelModel.hero
|
||||||
Label.setLabel(self, withHTML: labelModel.html)
|
Label.setLabel(self, withHTML: labelModel.html)
|
||||||
|
isAccessibilityElement = hasText
|
||||||
|
|
||||||
let alignment = LabelAlignment(rawValue: labelModel.textAlignment ?? "")
|
switch labelModel.textAlignment {
|
||||||
switch alignment {
|
|
||||||
case .center:
|
case .center:
|
||||||
textAlignment = .center
|
textAlignment = .center
|
||||||
|
|
||||||
case .right:
|
case .right:
|
||||||
textAlignment = .right
|
textAlignment = .right
|
||||||
|
|
||||||
default:
|
default:
|
||||||
textAlignment = .left
|
textAlignment = .left
|
||||||
}
|
}
|
||||||
@ -338,8 +343,7 @@ public typealias ActionBlock = () -> ()
|
|||||||
accessibilityLabel = accessibilityText
|
accessibilityLabel = accessibilityText
|
||||||
}
|
}
|
||||||
|
|
||||||
if let fontStyle = labelModel.fontStyle {
|
if let fontStyle = labelModel.fontStyle?.rawValue {
|
||||||
MFStyler.styleLabel(self, withStyle: fontStyle)
|
|
||||||
MFStyler.styleLabel(self, withStyle: fontStyle, genericScaling: false)
|
MFStyler.styleLabel(self, withStyle: fontStyle, genericScaling: false)
|
||||||
standardFontSize = font.pointSize
|
standardFontSize = font.pointSize
|
||||||
} else {
|
} else {
|
||||||
@ -372,9 +376,9 @@ public typealias ActionBlock = () -> ()
|
|||||||
attributedString.addAttribute(.baselineOffset, value: 0, range: range)
|
attributedString.addAttribute(.baselineOffset, value: 0, range: range)
|
||||||
|
|
||||||
case let colorAtt as LabelAttributeColorModel:
|
case let colorAtt as LabelAttributeColorModel:
|
||||||
if let colorHex = colorAtt.textColor, !colorHex.isEmpty {
|
if let colorHex = colorAtt.textColor {
|
||||||
attributedString.removeAttribute(.foregroundColor, range: range)
|
attributedString.removeAttribute(.foregroundColor, range: range)
|
||||||
attributedString.addAttribute(.foregroundColor, value: UIColor.mfGet(forHex: colorHex), range: range)
|
attributedString.addAttribute(.foregroundColor, value: colorHex.uiColor, range: range)
|
||||||
}
|
}
|
||||||
|
|
||||||
case let imageAtt as LabelAttributeImageModel:
|
case let imageAtt as LabelAttributeImageModel:
|
||||||
@ -395,7 +399,7 @@ public typealias ActionBlock = () -> ()
|
|||||||
attributedString.insert(mutableString, at: imageAtt.location)
|
attributedString.insert(mutableString, at: imageAtt.location)
|
||||||
|
|
||||||
case let fontAtt as LabelAttributeFontModel:
|
case let fontAtt as LabelAttributeFontModel:
|
||||||
if let fontStyle = fontAtt.style {
|
if let fontStyle = fontAtt.style?.rawValue {
|
||||||
let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle)
|
let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle)
|
||||||
attributedString.removeAttribute(.font, range: range)
|
attributedString.removeAttribute(.font, range: range)
|
||||||
attributedString.removeAttribute(.foregroundColor, range: range)
|
attributedString.removeAttribute(.foregroundColor, range: range)
|
||||||
@ -426,6 +430,7 @@ public typealias ActionBlock = () -> ()
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attributedText = attributedString
|
attributedText = attributedString
|
||||||
originalAttributedString = attributedText
|
originalAttributedString = attributedText
|
||||||
}
|
}
|
||||||
@ -865,16 +870,6 @@ extension Label {
|
|||||||
accessibilityTraits = .staticText
|
accessibilityTraits = .staticText
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
clauses = []
|
|
||||||
Label.setUILabel(self, withJSON: json, delegate: delegateObject, additionalData: additionalData)
|
|
||||||
hero = json?["hero"] as? Int
|
|
||||||
}
|
|
||||||
|
|
||||||
public func setAsMolecule() {
|
|
||||||
styleB2(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func needsToBeConstrained() -> Bool {
|
public func needsToBeConstrained() -> Bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -17,7 +17,7 @@ import UIKit
|
|||||||
return "color"
|
return "color"
|
||||||
}
|
}
|
||||||
|
|
||||||
var textColor: String?
|
var textColor: Color?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
@ -33,7 +33,7 @@ import UIKit
|
|||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor)
|
textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor)
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ import UIKit
|
|||||||
return "font"
|
return "font"
|
||||||
}
|
}
|
||||||
|
|
||||||
var style: String?
|
var style: LabelModel.FontStyle?
|
||||||
var name: String?
|
var name: String?
|
||||||
var size: CGFloat?
|
var size: CGFloat?
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ import UIKit
|
|||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
style = try typeContainer.decodeIfPresent(String.self, forKey: .style)
|
style = try typeContainer.decodeIfPresent(LabelModel.FontStyle.self, forKey: .style)
|
||||||
name = try typeContainer.decodeIfPresent(String.self, forKey: .name)
|
name = try typeContainer.decodeIfPresent(String.self, forKey: .name)
|
||||||
size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size)
|
size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size)
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
@ -32,7 +32,7 @@ import Foundation
|
|||||||
var location: Int
|
var location: Int
|
||||||
var length: Int
|
var length: Int
|
||||||
|
|
||||||
init(_ location: Int, _ length: Int) {
|
public init(_ location: Int, _ length: Int) {
|
||||||
self.location = location
|
self.location = location
|
||||||
self.length = length
|
self.length = length
|
||||||
}
|
}
|
||||||
@ -19,4 +19,8 @@ import UIKit
|
|||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override init(_ location: Int, _ length: Int) {
|
||||||
|
super.init(location, length)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -10,6 +10,31 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class LabelModel: MoleculeModelProtocol {
|
@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
|
||||||
|
case H32
|
||||||
|
case B1
|
||||||
|
case B2
|
||||||
|
case B3
|
||||||
|
case B20
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -19,10 +44,10 @@ import Foundation
|
|||||||
public var text: String
|
public var text: String
|
||||||
public var accessibilityText: String?
|
public var accessibilityText: String?
|
||||||
public var textColor: Color?
|
public var textColor: Color?
|
||||||
public var fontStyle: String?
|
public var fontStyle: FontStyle?
|
||||||
public var fontName: String?
|
public var fontName: String?
|
||||||
public var fontSize: CGFloat?
|
public var fontSize: CGFloat?
|
||||||
public var textAlignment: String?
|
public var textAlignment: NSTextAlignment?
|
||||||
public var attributes: [LabelAttributeModel]?
|
public var attributes: [LabelAttributeModel]?
|
||||||
public var html: String?
|
public var html: String?
|
||||||
public var hero: Int?
|
public var hero: Int?
|
||||||
@ -70,10 +95,10 @@ import Foundation
|
|||||||
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||||
textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor)
|
textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor)
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
fontStyle = try typeContainer.decodeIfPresent(String.self, forKey: .fontStyle)
|
fontStyle = try typeContainer.decodeIfPresent(FontStyle.self, forKey: .fontStyle)
|
||||||
fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName)
|
fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName)
|
||||||
fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize)
|
fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize)
|
||||||
textAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .textAlignment)
|
textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment)
|
||||||
attributes = try typeContainer.decodeModelsIfPresent(codingKey: .attributes)
|
attributes = try typeContainer.decodeModelsIfPresent(codingKey: .attributes)
|
||||||
html = try typeContainer.decodeIfPresent(String.self, forKey: .html)
|
html = try typeContainer.decodeIfPresent(String.self, forKey: .html)
|
||||||
hero = try typeContainer.decodeIfPresent(Int.self, forKey: .hero)
|
hero = try typeContainer.decodeIfPresent(Int.self, forKey: .hero)
|
||||||
29
MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift
Normal file
29
MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// LeftRightLabelModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Ryan on 12/12/19.
|
||||||
|
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objcMembers open class LeftRightLabelModel: MoleculeModelProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public static var identifier: String = "leftRightLabelView"
|
||||||
|
public var moleculeName: String = LeftRightLabelModel.identifier
|
||||||
|
public var backgroundColor: Color?
|
||||||
|
public var leftText: LabelModel
|
||||||
|
public var rightText: LabelModel?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializer
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public init(_ leftText: LabelModel) {
|
||||||
|
self.leftText = leftText
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -40,11 +40,6 @@ import Foundation
|
|||||||
super.init(coder: aDecoder)
|
super.init(coder: aDecoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
public convenience init(json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
self.init()
|
|
||||||
setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
override open func setupView() {
|
override open func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
|
|
||||||
@ -162,23 +157,6 @@ import Foundation
|
|||||||
// MARK: - Atomization
|
// MARK: - Atomization
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
|
|
||||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject as? MVMCoreUIDelegateObject, additionalData: additionalData)
|
|
||||||
|
|
||||||
guard let dictionary = json else { return }
|
|
||||||
|
|
||||||
leftTextLabel.setWithJSON(dictionary.optionalDictionaryForKey("leftText"), delegateObject: delegateObject as? MVMCoreUIDelegateObject, additionalData: additionalData)
|
|
||||||
rightTextLabel.setWithJSON(dictionary.optionalDictionaryForKey("rightText"), delegateObject: delegateObject as? MVMCoreUIDelegateObject, additionalData: additionalData)
|
|
||||||
|
|
||||||
if !leftTextLabel.hasText {
|
|
||||||
constrainRightLabel()
|
|
||||||
} else if !rightTextLabel.hasText {
|
|
||||||
constrainLeftLabel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: - MVMCoreMoleculeViewProtocol
|
|
||||||
|
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
guard let leftRightLabelModel = model as? LeftRightLabelModel else {
|
guard let leftRightLabelModel = model as? LeftRightLabelModel else {
|
||||||
@ -54,22 +54,10 @@ import UIKit
|
|||||||
setStyle(.standard)
|
setStyle(.standard)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
open override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
|
||||||
|
|
||||||
// If no type, default to standard.
|
|
||||||
if let typeString = json?.optionalStringForKey(KeyType), let type = LineModel.Style.init(rawValue: typeString) {
|
|
||||||
setStyle(type)
|
|
||||||
} else {
|
|
||||||
setStyle(.standard)
|
|
||||||
}
|
|
||||||
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
if let lineModel = model as? LineModel {
|
if let lineModel = model as? LineModel {
|
||||||
setStyle(lineModel.type ?? .standard)
|
setStyle(lineModel.type)
|
||||||
}
|
}
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
@ -78,13 +66,9 @@ import UIKit
|
|||||||
setStyle(.standard)
|
setStyle(.standard)
|
||||||
}
|
}
|
||||||
|
|
||||||
open func copyBackgroundColor() -> Bool {
|
public override static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
return false
|
guard let type = (model as? LineModel)?.type else { return 1 }
|
||||||
}
|
switch type {
|
||||||
|
|
||||||
public static func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
|
||||||
guard let type = json?.optionalStringForKey(KeyType), let style = LineModel.Style(rawValue: type) else { return 1 }
|
|
||||||
switch style {
|
|
||||||
case .none:
|
case .none:
|
||||||
return 0
|
return 0
|
||||||
case .medium:
|
case .medium:
|
||||||
@ -101,4 +85,8 @@ extension Line: MVMCoreUIViewConstrainingProtocol {
|
|||||||
open func needsToBeConstrained() -> Bool {
|
open func needsToBeConstrained() -> Bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open func copyBackgroundColor() -> Bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@objcMembers open class MFLoadImageView: ViewConstrainingView, ModelMoleculeViewProtocol {
|
// TODO: Change to container instead of ViewConstraining without breaking legacy stack.
|
||||||
|
@objcMembers open class MFLoadImageView: ViewConstrainingView, MoleculeViewProtocol {
|
||||||
public let loadingSpinner = MFLoadingSpinner(frame: .zero)
|
public let loadingSpinner = MFLoadingSpinner(frame: .zero)
|
||||||
public let imageView = MFTransparentGIFView(frame: .zero)
|
public let imageView = MFTransparentGIFView(frame: .zero)
|
||||||
public var addSizeConstraintsForAspectRatio = false
|
public var addSizeConstraintsForAspectRatio = false
|
||||||
@ -46,6 +47,13 @@ import UIKit
|
|||||||
super.init(coder: aDecoder)
|
super.init(coder: aDecoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.init(frame: .zero)
|
||||||
|
addSizeConstraintsForAspectRatio = true
|
||||||
|
pinEdges(.all)
|
||||||
|
set(with: model, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
public func pinEdges(_ edge: UIRectEdge) {
|
public func pinEdges(_ edge: UIRectEdge) {
|
||||||
edges = edge
|
edges = edge
|
||||||
if edge == UIRectEdge.all {
|
if edge == UIRectEdge.all {
|
||||||
@ -181,7 +189,7 @@ import UIKit
|
|||||||
let widthWillChange = !MVMCoreGetterUtility.cgfequal(widthConstraint?.constant ?? 0, width ?? 0)
|
let widthWillChange = !MVMCoreGetterUtility.cgfequal(widthConstraint?.constant ?? 0, width ?? 0)
|
||||||
let heightWillChange = !MVMCoreGetterUtility.cgfequal(heightConstraint?.constant ?? 0, height ?? 0)
|
let heightWillChange = !MVMCoreGetterUtility.cgfequal(heightConstraint?.constant ?? 0, height ?? 0)
|
||||||
let sizeWillChange = (width == nil || height == nil) && !(size?.equalTo(imageView.image?.size ?? CGSize.zero) ?? false)
|
let sizeWillChange = (width == nil || height == nil) && !(size?.equalTo(imageView.image?.size ?? CGSize.zero) ?? false)
|
||||||
let heightChangeFromSpinner = ((height ?? size?.height) ?? 0) < loadingSpinnerHeightConstraint?.constant ?? CGFloat.leastNormalMagnitude
|
let heightChangeFromSpinner = (heightConstraint?.isActive ?? false) ? false : ((height ?? size?.height) ?? 0) < loadingSpinnerHeightConstraint?.constant ?? CGFloat.leastNormalMagnitude
|
||||||
return widthWillChange || heightWillChange || sizeWillChange || heightChangeFromSpinner
|
return widthWillChange || heightWillChange || sizeWillChange || heightChangeFromSpinner
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,11 +219,7 @@ import UIKit
|
|||||||
|
|
||||||
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
self.delegateObject = delegateObject
|
self.delegateObject = delegateObject
|
||||||
// TODO: Temporary, should be moved to init once we have type erasure ready.
|
guard let imageModel = model as? ImageViewModel else { return }
|
||||||
setAsMolecule()
|
|
||||||
guard let imageModel = model as? ImageViewModel else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if let accessibilityString = imageModel.accessibilityText {
|
if let accessibilityString = imageModel.accessibilityText {
|
||||||
imageView.accessibilityLabel = accessibilityString
|
imageView.accessibilityLabel = accessibilityString
|
||||||
imageView.accessibilityTraits = .staticText
|
imageView.accessibilityTraits = .staticText
|
||||||
@ -241,40 +245,6 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol functions
|
|
||||||
open override func setAsMolecule() {
|
|
||||||
addSizeConstraintsForAspectRatio = true
|
|
||||||
pinEdges(.all)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
|
||||||
return json?.optionalCGFloatForKey("height") ?? 0
|
|
||||||
}
|
|
||||||
|
|
||||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
self.delegateObject = delegateObject
|
|
||||||
if let accessibilityString = json?.optionalStringForKey("accessibilityText") {
|
|
||||||
imageView.accessibilityLabel = accessibilityString
|
|
||||||
imageView.accessibilityTraits = .staticText
|
|
||||||
imageView.isAccessibilityElement = true
|
|
||||||
}
|
|
||||||
let width = json?.optionalCGFloatForKey("width") ?? imageWidth
|
|
||||||
let height = json?.optionalCGFloatForKey("height") ?? imageHeight
|
|
||||||
// For smoother transitions, set constraints that we know immediately.
|
|
||||||
if let width = width, addSizeConstraintsForAspectRatio {
|
|
||||||
setWidth(width)
|
|
||||||
}
|
|
||||||
if let height = height, addSizeConstraintsForAspectRatio {
|
|
||||||
setHeight(height)
|
|
||||||
}
|
|
||||||
if let imageName = json?.optionalStringForKey("image"), shouldLoadImage(withName: imageName, width: width, height: height) {
|
|
||||||
imageView.image = nil
|
|
||||||
imageView.animatedImage = nil
|
|
||||||
loadImage(withName: imageName, format: json?.optionalStringForKey("imageFormat"), width: width as NSNumber?, height: height as NSNumber?, customFallbackImage: json?.optionalStringForKey("fallbackImage"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - load functions
|
// MARK: - load functions
|
||||||
public func loadImage(withName imageName: String?, format: String? = nil, width: NSNumber? = nil, height: NSNumber? = nil, customFallbackImage: String? = nil, allowServerParameters: Bool = false, localBundle: Bundle? = nil, completionHandler: MVMCoreGetImageBlock? = nil) {
|
public func loadImage(withName imageName: String?, format: String? = nil, width: NSNumber? = nil, height: NSNumber? = nil, customFallbackImage: String? = nil, allowServerParameters: Bool = false, localBundle: Bundle? = nil, completionHandler: MVMCoreGetImageBlock? = nil) {
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - MVMCoreMoleculeViewProtocol
|
//MARK: - MoleculeViewProtocol
|
||||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
guard let multiProgressModel = multiProgressModel else {
|
guard let multiProgressModel = multiProgressModel else {
|
||||||
@ -81,8 +81,7 @@ import UIKit
|
|||||||
progressList = nil
|
progressList = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
guard let json = json, let model = try? Self.decodeJSONToModel(json: json, type: MultiProgressBarModel.self) else { return }
|
return (model as? MultiProgressBarModel)?.thickness ?? 8
|
||||||
set(with: model, delegateObject, additionalData)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers open class ProgressBar: UIProgressView, MVMCoreViewProtocol, ModelMoleculeViewProtocol, MVMCoreUIMoleculeViewProtocol {
|
@objcMembers open class ProgressBar: UIProgressView, MVMCoreViewProtocol, MoleculeViewProtocol {
|
||||||
var progressBarModel: ProgressBarModel?
|
var progressBarModel: ProgressBarModel?
|
||||||
|
|
||||||
var thickness: CGFloat = 8.0 {
|
var thickness: CGFloat = 8.0 {
|
||||||
@ -32,7 +32,7 @@ import Foundation
|
|||||||
setupView()
|
setupView()
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
public init() {
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
setupView()
|
setupView()
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ import Foundation
|
|||||||
public func updateView(_ size: CGFloat) {
|
public func updateView(_ size: CGFloat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - MVMCoreMoleculeViewProtocol
|
//MARK: - MoleculeViewProtocol
|
||||||
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
guard let progressBarModel = model as? ProgressBarModel else {
|
guard let progressBarModel = model as? ProgressBarModel else {
|
||||||
return
|
return
|
||||||
@ -63,12 +63,6 @@ import Foundation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
|
||||||
public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
guard let json = json, let model = try? Self.decodeJSONToModel(json: json, type: ProgressBarModel.self) else { return }
|
|
||||||
set(with: model, delegateObject, additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func reset() {
|
public func reset() {
|
||||||
thickness = 8
|
thickness = 8
|
||||||
progress = 0
|
progress = 0
|
||||||
@ -76,7 +70,7 @@ import Foundation
|
|||||||
trackTintColor = UIColor.mfLightSilver()
|
trackTintColor = UIColor.mfLightSilver()
|
||||||
}
|
}
|
||||||
|
|
||||||
public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
return 8
|
return 8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19,7 +19,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
Container: The background of the toggle control.
|
Container: The background of the toggle control.
|
||||||
Knob: The circular indicator that slides on the container.
|
Knob: The circular indicator that slides on the container.
|
||||||
*/
|
*/
|
||||||
@objcMembers open class Toggle: Control, MVMCoreUIViewConstrainingProtocol, FormValidationFormFieldProtocol {
|
@objcMembers open class Toggle: Control, MVMCoreUIViewConstrainingProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -100,8 +100,9 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
knobView.backgroundColor = isOn ? knobTintColor?.on : knobTintColor?.off
|
knobView.backgroundColor = isOn ? knobTintColor?.on : knobTintColor?.off
|
||||||
self.constrainKnob()
|
self.constrainKnob()
|
||||||
}
|
}
|
||||||
|
|
||||||
FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol)
|
(model as? ToggleModel)?.state = isOn
|
||||||
|
FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||||
accessibilityValue = isOn ? MVMCoreUIUtility.hardcodedString(withKey: "AccOn") : MVMCoreUIUtility.hardcodedString(withKey: "AccOff")
|
accessibilityValue = isOn ? MVMCoreUIUtility.hardcodedString(withKey: "AccOn") : MVMCoreUIUtility.hardcodedString(withKey: "AccOff")
|
||||||
setNeedsLayout()
|
setNeedsLayout()
|
||||||
layoutIfNeeded()
|
layoutIfNeeded()
|
||||||
@ -126,6 +127,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
private var widthConstraint: NSLayoutConstraint?
|
private var widthConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
private func constrainKnob() {
|
private func constrainKnob() {
|
||||||
|
|
||||||
knobLeadingConstraint?.isActive = !isOn
|
knobLeadingConstraint?.isActive = !isOn
|
||||||
knobTrailingConstraint?.isActive = isOn
|
knobTrailingConstraint?.isActive = isOn
|
||||||
}
|
}
|
||||||
@ -188,8 +190,11 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
|
|
||||||
public override func setupView() {
|
public override func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
|
|
||||||
guard subviews.isEmpty else { return }
|
guard subviews.isEmpty else { return }
|
||||||
|
isAccessibilityElement = true
|
||||||
|
accessibilityTraits = .button
|
||||||
|
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccToggleHint")
|
||||||
|
accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel")
|
||||||
|
|
||||||
heightConstraint = heightAnchor.constraint(equalToConstant: Self.containerSize.height)
|
heightConstraint = heightAnchor.constraint(equalToConstant: Self.containerSize.height)
|
||||||
heightConstraint?.isActive = true
|
heightConstraint?.isActive = true
|
||||||
@ -213,8 +218,6 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 1)
|
knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 1)
|
||||||
knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1)
|
knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1)
|
||||||
knobLeadingConstraint?.isActive = true
|
knobLeadingConstraint?.isActive = true
|
||||||
|
|
||||||
accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func reset() {
|
public override func reset() {
|
||||||
@ -333,14 +336,38 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK:- ModelMoleculeViewProtocol
|
// MARK:- MoleculeViewProtocol
|
||||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
guard let toggleModel = model as? ToggleModel else {
|
super.set(with: model, delegateObject, additionalData)
|
||||||
return
|
self.delegateObject = delegateObject
|
||||||
|
|
||||||
|
guard let model = model as? ToggleModel else { return }
|
||||||
|
|
||||||
|
FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate)
|
||||||
|
|
||||||
|
if let color = model.onTintColor?.uiColor {
|
||||||
|
containerTintColor?.on = color
|
||||||
}
|
}
|
||||||
|
|
||||||
let toggleModelJSON = toggleModel.toJSON()
|
if let color = model.offTintColor?.uiColor {
|
||||||
setWithJSON(toggleModelJSON, delegateObject: delegateObject, additionalData: additionalData)
|
containerTintColor?.off = color
|
||||||
|
}
|
||||||
|
|
||||||
|
if let color = model.onKnobTintColor?.uiColor {
|
||||||
|
knobTintColor?.on = color
|
||||||
|
}
|
||||||
|
|
||||||
|
if let color = model.offKnobTintColor?.uiColor {
|
||||||
|
knobTintColor?.off = color
|
||||||
|
}
|
||||||
|
|
||||||
|
changeStateNoAnimation(model.state)
|
||||||
|
isAnimated = model.animated
|
||||||
|
isEnabled = model.enabled
|
||||||
|
|
||||||
|
if let actionMap = model.action?.toJSON() {
|
||||||
|
didToggleAction = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
@ -348,78 +375,9 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Accessibility
|
// MARK: - MVMCoreUIViewConstrainingProtocol
|
||||||
extension Toggle {
|
extension Toggle {
|
||||||
|
|
||||||
public func formFieldGroupName() -> String? {
|
|
||||||
return json?["groupName"] as? String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - FormValidationProtocol
|
|
||||||
extension Toggle {
|
|
||||||
|
|
||||||
public func isValidField() -> Bool {
|
|
||||||
return isOn && json?["required"] as? Bool ?? false
|
|
||||||
}
|
|
||||||
|
|
||||||
public func formFieldName() -> String? {
|
|
||||||
return json?[KeyFieldKey] as? String ?? ""
|
|
||||||
}
|
|
||||||
|
|
||||||
public func formFieldValue() -> Any? {
|
|
||||||
return NSNumber(value: isOn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
|
||||||
extension Toggle {
|
|
||||||
|
|
||||||
public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
self.delegateObject = delegateObject
|
|
||||||
|
|
||||||
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
|
|
||||||
|
|
||||||
guard let dictionary = json else { return }
|
|
||||||
|
|
||||||
if let color = dictionary["onTintColor"] as? String {
|
|
||||||
containerTintColor?.on = UIColor.mfGet(forHex: color)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let color = dictionary["offTintColor"] as? String {
|
|
||||||
containerTintColor?.off = UIColor.mfGet(forHex: color)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let color = dictionary["onKnobTintColor"] as? String {
|
|
||||||
knobTintColor?.on = UIColor.mfGet(forHex: color)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let color = dictionary["offKnobTintColor"] as? String {
|
|
||||||
knobTintColor?.off = UIColor.mfGet(forHex: color)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let state = dictionary["state"] as? Bool {
|
|
||||||
changeStateNoAnimation(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let actionMap = dictionary.optionalDictionaryForKey("action") {
|
|
||||||
didToggleAction = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) }
|
|
||||||
}
|
|
||||||
|
|
||||||
if let isAnimated = dictionary["isAnimated"] as? Bool {
|
|
||||||
self.isAnimated = isAnimated
|
|
||||||
}
|
|
||||||
|
|
||||||
if let isEnabled = dictionary["isEnabled"] as? Bool{
|
|
||||||
self.isEnabled = isEnabled
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
|
||||||
return Self.getContainerHeight()
|
|
||||||
}
|
|
||||||
|
|
||||||
public func needsToBeConstrained() -> Bool {
|
public func needsToBeConstrained() -> Bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
114
MVMCoreUI/Atomic/Atoms/Views/ToggleModel.swift
Normal file
114
MVMCoreUI/Atomic/Atoms/Views/ToggleModel.swift
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
//
|
||||||
|
// ToggleModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 1/14/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableModelProtocol {
|
||||||
|
|
||||||
|
public static var identifier: String = "toggle"
|
||||||
|
public var backgroundColor: Color?
|
||||||
|
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 fieldKey: String?
|
||||||
|
public var groupName: String? = FormValidator.defaultGroupName
|
||||||
|
public var baseValue: AnyHashable?
|
||||||
|
public var onTintColor: Color?
|
||||||
|
public var offTintColor: Color?
|
||||||
|
public var onKnobTintColor: Color?
|
||||||
|
public var offKnobTintColor: Color?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Keys
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case state
|
||||||
|
case animated
|
||||||
|
case enabled
|
||||||
|
case action
|
||||||
|
case backgroundColor
|
||||||
|
case fieldKey
|
||||||
|
case alternateAction
|
||||||
|
case groupName
|
||||||
|
case accessibilityText
|
||||||
|
case onTintColor
|
||||||
|
case offTintColor
|
||||||
|
case onKnobTintColor
|
||||||
|
case offKnobTintColor
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Methods
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public func formFieldValue() -> AnyHashable? {
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializer
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public init(_ state: Bool) {
|
||||||
|
self.state = 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
|
||||||
|
}
|
||||||
|
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
||||||
|
self.enabled = enabled
|
||||||
|
}
|
||||||
|
if let animated = try typeContainer.decodeIfPresent(Bool.self, forKey: .animated) {
|
||||||
|
self.animated = animated
|
||||||
|
}
|
||||||
|
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
|
||||||
|
alternateAction = try typeContainer.decodeModelIfPresent(codingKey: .alternateAction)
|
||||||
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
|
onTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onTintColor)
|
||||||
|
offTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offTintColor)
|
||||||
|
onKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onKnobTintColor)
|
||||||
|
offKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offKnobTintColor)
|
||||||
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
|
self.groupName = groupName
|
||||||
|
}
|
||||||
|
|
||||||
|
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
|
try container.encodeModelIfPresent(action, forKey: .action)
|
||||||
|
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(fieldKey, forKey: .fieldKey)
|
||||||
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
|
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||||
|
}
|
||||||
|
}
|
||||||
89
MVMCoreUI/Atomic/Extensions/NSTextAlignment+Extension.swift
Normal file
89
MVMCoreUI/Atomic/Extensions/NSTextAlignment+Extension.swift
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
//
|
||||||
|
// NSTextAlignment+Extension.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 3/24/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/**
|
||||||
|
When using this class in codable for a String value from server.
|
||||||
|
|
||||||
|
Example use case....
|
||||||
|
|
||||||
|
var alignment: NSTextAlignment
|
||||||
|
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case alignment
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
let word = try container.decode(String.self, forKey: .alignment)
|
||||||
|
alignment = NSTextAlignment(rawValue: word)!
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(alignment.rawValueString, forKey: .alignment)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum TextAlignmentError: Error {
|
||||||
|
case notAnAlignment
|
||||||
|
}
|
||||||
|
|
||||||
|
extension NSTextAlignment: RawRepresentable {
|
||||||
|
|
||||||
|
init?(rawValue: String) {
|
||||||
|
switch rawValue {
|
||||||
|
case "left":
|
||||||
|
self = .left
|
||||||
|
case "center":
|
||||||
|
self = .center
|
||||||
|
case "right":
|
||||||
|
self = .right
|
||||||
|
case "justified":
|
||||||
|
self = .justified
|
||||||
|
case "natural":
|
||||||
|
self = .natural
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var rawValueString: String {
|
||||||
|
switch self {
|
||||||
|
case .left:
|
||||||
|
return "left"
|
||||||
|
case .center:
|
||||||
|
return "center"
|
||||||
|
case .right:
|
||||||
|
return "right"
|
||||||
|
case .justified:
|
||||||
|
return "justified"
|
||||||
|
case .natural:
|
||||||
|
return "natural"
|
||||||
|
@unknown default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension NSTextAlignment: Codable {
|
||||||
|
public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.singleValueContainer()
|
||||||
|
let string = try typeContainer.decode(String.self)
|
||||||
|
guard let alignment = NSTextAlignment(rawValue: string) else {
|
||||||
|
throw TextAlignmentError.notAnAlignment
|
||||||
|
}
|
||||||
|
self = alignment
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.singleValueContainer()
|
||||||
|
try container.encode(rawValueString)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
//
|
||||||
|
// UICollectionViewScrollPosition+Extension.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 3/24/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum ScrollPositionError: Error {
|
||||||
|
case notAPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UICollectionView.ScrollPosition: RawRepresentable {
|
||||||
|
|
||||||
|
init?(rawValue: String) {
|
||||||
|
switch rawValue {
|
||||||
|
case "left", "leading":
|
||||||
|
self = .left
|
||||||
|
case "centeredHorizontally", "center":
|
||||||
|
self = .centeredHorizontally
|
||||||
|
case "right", "trailing":
|
||||||
|
self = .right
|
||||||
|
case "top":
|
||||||
|
self = .top
|
||||||
|
case "bottom":
|
||||||
|
self = .bottom
|
||||||
|
case "centeredVertically":
|
||||||
|
self = .centeredVertically
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var rawValueString: String {
|
||||||
|
switch self {
|
||||||
|
case .left:
|
||||||
|
return "left"
|
||||||
|
case .centeredHorizontally:
|
||||||
|
return "centeredHorizontally"
|
||||||
|
case .right:
|
||||||
|
return "right"
|
||||||
|
case .top:
|
||||||
|
return "top"
|
||||||
|
case .bottom:
|
||||||
|
return "bottom"
|
||||||
|
case .centeredVertically:
|
||||||
|
return "centeredVertically"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UICollectionView.ScrollPosition: Codable {
|
||||||
|
public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.singleValueContainer()
|
||||||
|
let string = try typeContainer.decode(String.self)
|
||||||
|
guard let position = UICollectionView.ScrollPosition(rawValue: string) else {
|
||||||
|
throw ScrollPositionError.notAPosition
|
||||||
|
}
|
||||||
|
self = position
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.singleValueContainer()
|
||||||
|
try container.encode(rawValueString)
|
||||||
|
}
|
||||||
|
}
|
||||||
184
MVMCoreUI/Atomic/MoleculeObjectMapping.swift
Normal file
184
MVMCoreUI/Atomic/MoleculeObjectMapping.swift
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
//
|
||||||
|
// MoleculeObjectMapping.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Suresh, Kamlesh on 10/28/19.
|
||||||
|
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers public class MoleculeObjectMapping: NSObject {
|
||||||
|
|
||||||
|
public var moleculeMapping: [String: MoleculeViewProtocol.Type] = [:]
|
||||||
|
|
||||||
|
/// Returns the mapping object stored in the singleton
|
||||||
|
public static func shared() -> Self? {
|
||||||
|
return MVMCoreActionUtility.initializerClassCheck(CoreUIObject.sharedInstance()?.moleculeMap, classToVerify: self) as? Self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Registers the model with the model registry and the view with the mapper.
|
||||||
|
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
|
||||||
|
public func getMoleculeClass(_ model: MoleculeModelProtocol) -> MoleculeViewProtocol.Type? {
|
||||||
|
return moleculeMapping[model.moleculeName]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a molecule with the given model.
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call to register all of the CoreUI molecules.
|
||||||
|
public static func registerObjects() {
|
||||||
|
// Stacks
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeStackView.self, viewModelClass: MoleculeStackModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: Stack<StackModel>.self, viewModelClass: StackModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: UnOrderedList.self, viewModelClass: UnOrderedListModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: NumberedList.self, viewModelClass: NumberedListModel.self)
|
||||||
|
|
||||||
|
// Label
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: Label.self, viewModelClass: LabelModel.self)
|
||||||
|
// need to move labelattributemodel to different method
|
||||||
|
try? ModelRegistry.register(LabelAttributeFontModel.self)
|
||||||
|
try? ModelRegistry.register(LabelAttributeColorModel.self)
|
||||||
|
try? ModelRegistry.register(LabelAttributeImageModel.self) // We need to separate the registry by types due to collisions...
|
||||||
|
try? ModelRegistry.register(LabelAttributeUnderlineModel.self)
|
||||||
|
try? ModelRegistry.register(LabelAttributeStrikeThroughModel.self)
|
||||||
|
try? ModelRegistry.register(LabelAttributeActionModel.self)
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: TwoButtonView.self, viewModelClass: TwoButtonViewModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ExternalLink.self, viewModelClass: ExternalLinkModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: Link.self, viewModelClass: LinkModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: CaretLink.self, viewModelClass: CaretLinkModel.self)
|
||||||
|
|
||||||
|
// Entry Field
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: TextEntryField.self, viewModelClass: TextEntryFieldModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: MdnEntryField.self, viewModelClass: MdnEntryFieldModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: DigitEntryField.self, viewModelClass: DigitEntryFieldModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ItemDropdownEntryField.self, viewModelClass: ItemDropdownEntryFieldModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: DateDropdownEntryField.self, viewModelClass: DateDropdownEntryFieldModel.self)
|
||||||
|
|
||||||
|
// Other Atoms
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: CaretView.self, viewModelClass: CaretViewModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: DashLine.self, viewModelClass: DashLineModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: MFLoadImageView.self, viewModelClass: ImageViewModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: Line.self, viewModelClass: LineModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: GraphView.self, viewModelClass: CircleProgressModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: CheckboxLabel.self, viewModelClass: CheckboxLabelModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: Arrow.self, viewModelClass: ArrowModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: RadioButtonLabel.self, viewModelClass: RadioButtonLabelModel.self)
|
||||||
|
|
||||||
|
// Horizontal Combination Molecules
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self)
|
||||||
|
|
||||||
|
// Vertical Combination Molecules
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: HeadLineBodyCaretLinkImage.self, viewModelClass: HeadlineBodyCaretLinkImageModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: EyebrowHeadlineBodyLink.self, viewModelClass: EyebrowHeadlineBodyLinkModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyLink.self, viewModelClass: HeadlineBodyLinkModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyButton.self, viewModelClass: HeadlineBodyButtonModel.self)
|
||||||
|
|
||||||
|
// Left Right Molecules
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: CornerLabels.self, viewModelClass: CornerLabelsModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: LeftRightLabelView.self, viewModelClass: LeftRightLabelModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: LabelToggle.self, viewModelClass: LabelToggleModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyToggle.self, viewModelClass: HeadlineBodyToggleModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyLinkToggle.self, viewModelClass: HeadlineBodyLinkToggleModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ActionDetailWithImage.self, viewModelClass: ActionDetailWithImageModel.self)
|
||||||
|
|
||||||
|
// List items
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeTableViewCell.self, viewModelClass: MoleculeListItemModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: DropDownFilterTableViewCell.self, viewModelClass: DropDownListItemModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: AccordionMoleculeTableViewCell.self, viewModelClass: AccordionListItemModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: TabsTableViewCell.self, viewModelClass: TabsListItemModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListProgressBarData.self, viewModelClass: ListProgressBarDataModel.self)
|
||||||
|
|
||||||
|
// Other Items
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeStackItem.self, viewModelClass: MoleculeStackItemModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: StackItem.self, viewModelClass: StackItemModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeCollectionViewCell.self, viewModelClass: CarouselItemModel.self)
|
||||||
|
|
||||||
|
// Other Container Molecules
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeHeaderView.self, viewModelClass: MoleculeHeaderModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: FooterView.self, viewModelClass: FooterModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: Scroller.self, viewModelClass: ScrollerModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ModuleMolecule.self, viewModelClass: ModuleMoleculeModel.self)
|
||||||
|
|
||||||
|
// Other Molecules
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: DoughnutChartView.self, viewModelClass: DoughnutChartModel.self)
|
||||||
|
|
||||||
|
// Other Organisms
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: Carousel.self, viewModelClass: CarouselModel.self)
|
||||||
|
|
||||||
|
// Designed List Items
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaret.self, viewModelClass: ListLeftVariableIconWithRightCaretModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxAllTextAndLinks.self, viewModelClass: ListLeftVariableCheckboxAllTextAndLinksModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonAndPaymentMethod.self, viewModelClass: ListLeftVariableRadioButtonAndPaymentMethodModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTotalData.self, viewModelClass: ListRightVariableTotalDataModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextAllTextAndLinks.self, viewModelClass: ListOneColumnFullWidthTextAllTextAndLinksModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextBodyText.self, viewModelClass: ListOneColumnFullWidthTextBodyTextModel.self)
|
||||||
|
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)
|
||||||
|
|
||||||
|
// Designed Section Dividers
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnPlanDataDivider.self, viewModelClass: ListThreeColumnPlanDataDividerModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnTextWithWhitespaceDividerShort.self, viewModelClass: ListOneColumnTextWithWhitespaceDividerShortModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnTextWithWhitespaceDividerTall.self, viewModelClass: ListOneColumnTextWithWhitespaceDividerTallModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextDividerSubsection.self, viewModelClass: ListOneColumnFullWidthTextDividerSubsectionModel.self)
|
||||||
|
|
||||||
|
// Designed Headers
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2NoButtonsBodyText.self, viewModelClass: HeadersH2NoButtonsBodyTextModel.self)
|
||||||
|
|
||||||
|
// TODO: Need View
|
||||||
|
try? ModelRegistry.register(TabsModel.self)
|
||||||
|
|
||||||
|
// Helper models
|
||||||
|
try? ModelRegistry.register(RuleRequiredModel.self)
|
||||||
|
try? ModelRegistry.register(RuleAnyRequiredModel.self)
|
||||||
|
try? ModelRegistry.register(RuleAnyValueChangedModel.self)
|
||||||
|
try? ModelRegistry.register(RuleAllValueChangedModel.self)
|
||||||
|
try? ModelRegistry.register(RuleEqualsModel.self)
|
||||||
|
try? ModelRegistry.register(RuleRegexModel.self)
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
try? ModelRegistry.register(ActionTopAlertModel.self)
|
||||||
|
try? ModelRegistry.register(ActionCollapseNotificationModel.self)
|
||||||
|
try? ModelRegistry.register(ActionOpenPanelModel.self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience function to get required modules for a give model
|
||||||
|
public static func getRequiredModules(for model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
||||||
|
guard let model = model else { return nil }
|
||||||
|
return MoleculeObjectMapping.shared()?.getMoleculeClass(model)?.requiredModules(with: model, delegateObject, error: error)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience function to add require modules for the given model to the passed in array.
|
||||||
|
public static func addRequiredModules(for model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, moduleList: inout [String]?, errorList: inout [MVMCoreErrorObject]?) {
|
||||||
|
guard let model = model else { return }
|
||||||
|
let error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>? = nil
|
||||||
|
if let modules = getRequiredModules(for: model, delegateObject, error: error) {
|
||||||
|
moduleList?.append(contentsOf: modules)
|
||||||
|
}
|
||||||
|
if let error = error?.pointee {
|
||||||
|
errorList?.append(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// HeadersH2NoButtonsBodyText.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 05/03/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers open class HeadersH2NoButtonsBodyText: HeaderView {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Outlets
|
||||||
|
//--------------------------------------------------
|
||||||
|
let headlineBody = HeadlineBody(frame: .zero)
|
||||||
|
|
||||||
|
//-------------------------------------------------------
|
||||||
|
// MARK: - View Lifecycle
|
||||||
|
//-------------------------------------------------------
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
headlineBody.stylePageHeader()
|
||||||
|
addMolecule(headlineBody)
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------
|
||||||
|
// 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? HeadersH2NoButtonsBodyTextModel else { return }
|
||||||
|
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
return 121
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func reset() {
|
||||||
|
super.reset()
|
||||||
|
headlineBody.stylePageHeader()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// HeadersH2NoButtonsBodyTextModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 05/03/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class HeadersH2NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
public static var identifier: String = "headerH2"
|
||||||
|
public var headlineBody: HeadlineBodyModel
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializer
|
||||||
|
//--------------------------------------------------
|
||||||
|
public init(headlineBody: HeadlineBodyModel) {
|
||||||
|
self.headlineBody = headlineBody
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
|
topMarginPadding = PaddingDefaultVerticalSpacing3
|
||||||
|
bottomMarginPadding = PaddingDefaultVerticalSpacing3
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Keys
|
||||||
|
//--------------------------------------------------
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case headlineBody
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codec
|
||||||
|
//--------------------------------------------------
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody)
|
||||||
|
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(headlineBody, forKey: .headlineBody)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,11 +9,18 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers open class ListLeftVariableCheckboxAllTextAndLinks: TableViewCell {
|
@objcMembers open class ListLeftVariableCheckboxAllTextAndLinks: TableViewCell {
|
||||||
public let checkbox = Checkbox(frame: .zero)
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public let checkbox = Checkbox()
|
||||||
public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero)
|
public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero)
|
||||||
public var stack: Stack<StackModel>
|
public var stack: Stack<StackModel>
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
stack = Stack<StackModel>.createStack(with: [(view: checkbox, model: StackItemModel(horizontalAlignment: .fill)),
|
stack = Stack<StackModel>.createStack(with: [(view: checkbox, model: StackItemModel(horizontalAlignment: .fill)),
|
||||||
(view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))],
|
(view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))],
|
||||||
@ -25,17 +32,25 @@ import Foundation
|
|||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - View Lifecycle
|
//--------------------------------------------------
|
||||||
|
// MARK: - Life Cycle
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
override open func setupView() {
|
override open func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
addMolecule(stack)
|
addMolecule(stack)
|
||||||
stack.restack()
|
stack.restack()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK:- MVMCoreUIMoleculeViewProtocol
|
//--------------------------------------------------
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
guard let model = model as? ListLeftVariableCheckboxAllTextAndLinksModel else { return}
|
|
||||||
|
guard let model = model as? ListLeftVariableCheckboxAllTextAndLinksModel else { return }
|
||||||
|
|
||||||
checkbox.set(with: model.checkbox, delegateObject, additionalData)
|
checkbox.set(with: model.checkbox, delegateObject, additionalData)
|
||||||
eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData)
|
eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
@ -9,10 +9,10 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@objcMembers open class ListLeftVariableRadioButtonAndPaymentMethod: TableViewCell {
|
@objcMembers open class ListLeftVariableRadioButtonAndPaymentMethod: TableViewCell {
|
||||||
|
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
// MARK: - Outlets
|
// MARK: - Outlets
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
|
||||||
let radioButton = RadioButton(frame: .zero)
|
let radioButton = RadioButton(frame: .zero)
|
||||||
let leftImage = MFLoadImageView(pinnedEdges: .all)
|
let leftImage = MFLoadImageView(pinnedEdges: .all)
|
||||||
let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink()
|
let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink()
|
||||||
@ -21,6 +21,7 @@ import UIKit
|
|||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
|
||||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
stack = Stack<StackModel>.createStack(with: [(view: radioButton, model: StackItemModel(horizontalAlignment: .fill)),
|
stack = Stack<StackModel>.createStack(with: [(view: radioButton, model: StackItemModel(horizontalAlignment: .fill)),
|
||||||
(view: leftImage, model: StackItemModel(horizontalAlignment: .fill)),
|
(view: leftImage, model: StackItemModel(horizontalAlignment: .fill)),
|
||||||
@ -36,8 +37,10 @@ import UIKit
|
|||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
// MARK: - View Lifecycle
|
// MARK: - View Lifecycle
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
|
||||||
override open func setupView() {
|
override open func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
|
leftImage.addSizeConstraintsForAspectRatio = true
|
||||||
addMolecule(stack)
|
addMolecule(stack)
|
||||||
stack.restack()
|
stack.restack()
|
||||||
eyebrowHeadlineBodyLink.body.textColor = .mvmOrangeAA
|
eyebrowHeadlineBodyLink.body.textColor = .mvmOrangeAA
|
||||||
@ -53,6 +56,7 @@ import UIKit
|
|||||||
//----------------------------------------------------
|
//----------------------------------------------------
|
||||||
// MARK: - Molecule
|
// MARK: - Molecule
|
||||||
//----------------------------------------------------
|
//----------------------------------------------------
|
||||||
|
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
guard let model = model as? ListLeftVariableRadioButtonAndPaymentMethodModel else { return}
|
guard let model = model as? ListLeftVariableRadioButtonAndPaymentMethodModel else { return}
|
||||||
@ -64,4 +68,8 @@ import UIKit
|
|||||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
return 90
|
return 90
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||||
|
radioButton.tapAction()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// ListOneColumnFullWidthTextBodyText.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kruthika KP on 05/03/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers open class ListOneColumnFullWidthTextBodyText: TableViewCell {
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Outlets
|
||||||
|
//-----------------------------------------------------
|
||||||
|
public var headlineBody = HeadlineBody(frame: .zero)
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - View Lifecycle
|
||||||
|
//-----------------------------------------------------
|
||||||
|
override open func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
addMolecule(headlineBody)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?){
|
||||||
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
guard let model = model as? ListOneColumnFullWidthTextBodyTextModel else { return }
|
||||||
|
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
return 90
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// ListOneColumnFullWidthTextBodyTextModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kruthika KP on 05/03/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class ListOneColumnFullWidthTextBodyTextModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "list1CFWBdy"
|
||||||
|
public var headlineBody: HeadlineBodyModel
|
||||||
|
|
||||||
|
public init(headlineBody: HeadlineBodyModel) {
|
||||||
|
self.headlineBody = headlineBody
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defaults to set
|
||||||
|
override public func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
|
headlineBody.style = .item
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case headlineBody
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody)
|
||||||
|
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(headlineBody, forKey: .headlineBody)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -39,7 +39,7 @@ import Foundation
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// MARK: - ModelMoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
@ -50,7 +50,7 @@ import Foundation
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
@ -36,6 +36,7 @@ import Foundation
|
|||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
override open func setupView() {
|
override open func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
|
rightImage.addSizeConstraintsForAspectRatio = true
|
||||||
addMolecule(stack)
|
addMolecule(stack)
|
||||||
stack.restack()
|
stack.restack()
|
||||||
}
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
//
|
||||||
|
// ListRightVariableTotalData.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kruthika KP on 02/03/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers open class ListRightVariableTotalData: TableViewCell {
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Outlets
|
||||||
|
//-----------------------------------------------------
|
||||||
|
public var stack: Stack<StackModel>
|
||||||
|
public let leftLabel = Label.commonLabelB1(true)
|
||||||
|
public let rightLabel = Label.commonLabelB2(true)
|
||||||
|
public let bar = Line()
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
stack = Stack<StackModel>.createStack(with: [(view: leftLabel, model: StackItemModel(horizontalAlignment: .leading)),
|
||||||
|
(view: bar, model: StackItemModel(horizontalAlignment: .fill)),
|
||||||
|
(view: rightLabel, model: StackItemModel(spacing: 4, horizontalAlignment: .fill))],
|
||||||
|
axis: .horizontal)
|
||||||
|
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()
|
||||||
|
bar.setStyle(.heavy)
|
||||||
|
bar.widthAnchor.constraint(equalToConstant: 20).isActive = true
|
||||||
|
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
|
||||||
|
addMolecule(stack)
|
||||||
|
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? ListRightVariableTotalDataModel else { return }
|
||||||
|
leftLabel.set(with: model.leftLabel, delegateObject, additionalData)
|
||||||
|
rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
|
||||||
|
bar.set(with: model.bar, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override class func estimatedHeight(with molecule: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat?{
|
||||||
|
return 70
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func reset() {
|
||||||
|
super.reset()
|
||||||
|
leftLabel.styleB1(true)
|
||||||
|
rightLabel.styleB2(true)
|
||||||
|
bar.setStyle(.heavy)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// ListRightVariableTotalDataModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kruthika KP on 02/03/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class ListRightVariableTotalDataModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
|
||||||
|
public static var identifier: String = "listRVLine"
|
||||||
|
public var leftLabel: LabelModel
|
||||||
|
public var rightLabel: LabelModel
|
||||||
|
public var bar: LineModel
|
||||||
|
|
||||||
|
override public func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
|
rightLabel.hero = 0
|
||||||
|
bar.type = .heavy
|
||||||
|
if bar.backgroundColor == nil {
|
||||||
|
bar.backgroundColor = Color(uiColor: .mvmBlue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public init (leftLabel: LabelModel, rightlabel:LabelModel, bar: LineModel){
|
||||||
|
self.leftLabel = leftLabel
|
||||||
|
self.rightLabel = rightlabel
|
||||||
|
self.bar = bar
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey{
|
||||||
|
case moleculeName
|
||||||
|
case leftLabel
|
||||||
|
case rightLabel
|
||||||
|
case bar
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel)
|
||||||
|
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
|
||||||
|
bar = try typeContainer.decode(LineModel.self, forKey: .bar)
|
||||||
|
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(leftLabel, forKey: .leftLabel)
|
||||||
|
try container.encode(rightLabel, forKey: .rightLabel)
|
||||||
|
try container.encode(bar, forKey: .bar)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,113 @@
|
|||||||
|
//
|
||||||
|
// ListTwoColumnCompareChanges.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 24/02/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers open class ListTwoColumnCompareChanges: TableViewCell {
|
||||||
|
|
||||||
|
//-------------------------------------------------------
|
||||||
|
// MARK: - Outlets
|
||||||
|
//-------------------------------------------------------
|
||||||
|
let leftHeadline1 = Label.commonLabelB1(true)
|
||||||
|
let leftHeadline2 = Label.commonLabelB1(true)
|
||||||
|
let leftHeadline3 = Label.commonLabelB1(true)
|
||||||
|
let leftBody = Label.commonLabelB2(true)
|
||||||
|
let leftLink = Link()
|
||||||
|
let rightHeadline1 = Label.commonLabelB1(true)
|
||||||
|
let rightHeadline2 = Label.commonLabelB1(true)
|
||||||
|
let rightHeadline3 = Label.commonLabelB1(true)
|
||||||
|
let rightBody = Label.commonLabelB2(true)
|
||||||
|
let rightLink = Link()
|
||||||
|
let containingStack: Stack<StackModel>
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//------------------------------------------------------
|
||||||
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
let stackHeadline1 = Stack<StackModel>.createStack(with: [(view: leftHeadline1, model: StackItemModel(percent: 50, verticalAlignment: .leading)),
|
||||||
|
(view: rightHeadline1, model: StackItemModel(percent: 50, verticalAlignment: .leading))],
|
||||||
|
axis: .horizontal)
|
||||||
|
let stackHeadline2 = Stack<StackModel>.createStack(with: [(view: leftHeadline2, model: StackItemModel(percent: 50, verticalAlignment: .leading)),
|
||||||
|
(view: rightHeadline2, model: StackItemModel(percent: 50, verticalAlignment: .leading))],
|
||||||
|
axis: .horizontal)
|
||||||
|
let stackHeadline3 = Stack<StackModel>.createStack(with: [(view: leftHeadline3, model: StackItemModel(percent: 50, verticalAlignment: .leading)),
|
||||||
|
(view: rightHeadline3, model: StackItemModel(percent: 50, verticalAlignment: .leading))],
|
||||||
|
axis: .horizontal)
|
||||||
|
let stackBody = Stack<StackModel>.createStack(with: [(view: leftBody, model: StackItemModel(percent: 50, verticalAlignment: .leading)),
|
||||||
|
(view: rightBody, model: StackItemModel(percent: 50, verticalAlignment: .leading))],
|
||||||
|
axis: .horizontal)
|
||||||
|
let stackLink = Stack<StackModel>.createStack(with: [(view: leftLink, model: StackItemModel(percent: 50, verticalAlignment: .leading)),
|
||||||
|
(view: rightLink, model: StackItemModel(percent: 50, verticalAlignment: .leading))],
|
||||||
|
axis: .horizontal)
|
||||||
|
containingStack = Stack<StackModel>.createStack(with: [stackHeadline1,
|
||||||
|
stackHeadline2,
|
||||||
|
stackHeadline3,
|
||||||
|
stackBody,
|
||||||
|
stackLink],
|
||||||
|
spacing: 0)
|
||||||
|
containingStack.stackModel?.molecules[1].spacing = 5
|
||||||
|
containingStack.stackModel?.molecules[2].spacing = 5
|
||||||
|
containingStack.stackModel?.molecules[4].spacing = 5
|
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
public required init?(coder aDecoder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//------------------------------------------------------
|
||||||
|
let stackSpacing: CGFloat = 5.0
|
||||||
|
|
||||||
|
//-------------------------------------------------------
|
||||||
|
// MARK: - View Lifecycle
|
||||||
|
//-------------------------------------------------------
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
addMolecule(containingStack)
|
||||||
|
for molecule in containingStack.stackItems {
|
||||||
|
((molecule as? StackItem)?.view as? Stack<StackModel>)?.restack()
|
||||||
|
}
|
||||||
|
containingStack.restack()
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
// 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? ListTwoColumnCompareChangesModel else { return }
|
||||||
|
leftHeadline1.set(with: model.leftHeadline1, delegateObject, additionalData)
|
||||||
|
leftHeadline2.set(with: model.leftHeadline2, delegateObject, additionalData)
|
||||||
|
leftHeadline3.set(with: model.leftHeadline3, delegateObject, additionalData)
|
||||||
|
leftBody.set(with: model.leftBody, delegateObject, additionalData)
|
||||||
|
leftLink.set(with: model.leftLink, delegateObject, additionalData)
|
||||||
|
rightHeadline1.set(with: model.rightHeadline1, delegateObject, additionalData)
|
||||||
|
rightHeadline2.set(with: model.rightHeadline2, delegateObject, additionalData)
|
||||||
|
rightHeadline3.set(with: model.rightHeadline3, delegateObject, additionalData)
|
||||||
|
rightBody.set(with: model.rightBody, delegateObject, additionalData)
|
||||||
|
rightLink.set(with: model.rightLink, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func reset() {
|
||||||
|
super.reset()
|
||||||
|
leftHeadline1.styleB1(true)
|
||||||
|
leftHeadline2.styleB1(true)
|
||||||
|
leftHeadline3.styleB1(true)
|
||||||
|
leftBody.styleB2(true)
|
||||||
|
rightHeadline1.styleB1(true)
|
||||||
|
rightHeadline2.styleB1(true)
|
||||||
|
rightHeadline3.styleB1(true)
|
||||||
|
rightBody.styleB2(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override class func estimatedHeight(with molecule: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||||
|
return 121
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
//
|
||||||
|
// ListTwoColumnCompareChangesModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 24/02/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class ListTwoColumnCompareChangesModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
|
||||||
|
public static var identifier: String = "list2CCmpr1"
|
||||||
|
public var leftHeadline1: LabelModel
|
||||||
|
public var leftHeadline2: LabelModel
|
||||||
|
public var leftHeadline3: LabelModel
|
||||||
|
public var leftBody: LabelModel
|
||||||
|
public var leftLink: LinkModel
|
||||||
|
public var rightHeadline1: LabelModel
|
||||||
|
public var rightHeadline2: LabelModel
|
||||||
|
public var rightHeadline3: LabelModel
|
||||||
|
public var rightBody: LabelModel
|
||||||
|
public var rightLink: LinkModel
|
||||||
|
|
||||||
|
public init(leftHeadline1: LabelModel, leftHeadline2: LabelModel, leftHeadline3: LabelModel, leftBody: LabelModel, leftLink: LinkModel, rightHeadline1: LabelModel, rightHeadline2: LabelModel, rightHeadline3: LabelModel, rightBody: LabelModel, rightLink: LinkModel) {
|
||||||
|
self.leftHeadline1 = leftHeadline1
|
||||||
|
self.leftHeadline2 = leftHeadline2
|
||||||
|
self.leftHeadline3 = leftHeadline3
|
||||||
|
self.leftBody = leftBody
|
||||||
|
self.leftLink = leftLink
|
||||||
|
self.rightHeadline1 = rightHeadline1
|
||||||
|
self.rightHeadline2 = rightHeadline2
|
||||||
|
self.rightHeadline3 = rightHeadline3
|
||||||
|
self.rightBody = rightBody
|
||||||
|
self.rightLink = rightLink
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case leftHeadline1
|
||||||
|
case leftHeadline2
|
||||||
|
case leftHeadline3
|
||||||
|
case leftBody
|
||||||
|
case leftLink
|
||||||
|
case rightHeadline1
|
||||||
|
case rightHeadline2
|
||||||
|
case rightHeadline3
|
||||||
|
case rightBody
|
||||||
|
case rightLink
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
leftHeadline1 = try typeContainer.decode(LabelModel.self, forKey: .leftHeadline1)
|
||||||
|
leftHeadline2 = try typeContainer.decode(LabelModel.self, forKey: .leftHeadline2)
|
||||||
|
leftHeadline3 = try typeContainer.decode(LabelModel.self, forKey: .leftHeadline3)
|
||||||
|
leftBody = try typeContainer.decode(LabelModel.self, forKey: .leftBody)
|
||||||
|
leftLink = try typeContainer.decode(LinkModel.self, forKey: .leftLink)
|
||||||
|
rightHeadline1 = try typeContainer.decode(LabelModel.self, forKey: .rightHeadline1)
|
||||||
|
rightHeadline2 = try typeContainer.decode(LabelModel.self, forKey: .rightHeadline2)
|
||||||
|
rightHeadline3 = try typeContainer.decode(LabelModel.self, forKey: .rightHeadline3)
|
||||||
|
rightBody = try typeContainer.decode(LabelModel.self, forKey: .rightBody)
|
||||||
|
rightLink = try typeContainer.decode(LinkModel.self, forKey: .rightLink)
|
||||||
|
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(leftHeadline1, forKey: .leftHeadline1)
|
||||||
|
try container.encode(leftHeadline2, forKey: .leftHeadline2)
|
||||||
|
try container.encode(leftHeadline3, forKey: .leftHeadline3)
|
||||||
|
try container.encode(leftBody, forKey: .leftBody)
|
||||||
|
try container.encode(leftLink, forKey: .leftLink)
|
||||||
|
try container.encode(rightHeadline1, forKey: .rightHeadline1)
|
||||||
|
try container.encode(rightHeadline2, forKey: .rightHeadline2)
|
||||||
|
try container.encode(rightHeadline3, forKey: .rightHeadline3)
|
||||||
|
try container.encode(rightBody, forKey: .rightBody)
|
||||||
|
try container.encode(rightLink, forKey: .rightLink)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
//
|
||||||
|
// ListTwoColumnPriceDescription.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kruthika KP on 24/02/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers open class ListTwoColumnPriceDescription: TableViewCell {
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Outlets
|
||||||
|
//-------------------------------------------------------
|
||||||
|
public let leftHeadline = Label.commonLabelB1(true)
|
||||||
|
public let leftBody = Label.commonLabelB2(true)
|
||||||
|
public let rightLabel = Label.commonLabelB2(true)
|
||||||
|
public let rightSubLabel = Label.commonLabelB2(true)
|
||||||
|
|
||||||
|
public let view = MVMCoreUICommonViewsUtility.commonView()
|
||||||
|
public let leftVerticalStack: UIStackView
|
||||||
|
public let rightVerticalStack: UIStackView
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//------------------------------------------------------
|
||||||
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
leftVerticalStack = UIStackView(arrangedSubviews: [leftHeadline, leftBody])
|
||||||
|
leftVerticalStack.axis = .vertical
|
||||||
|
leftVerticalStack.alignment = .leading
|
||||||
|
rightVerticalStack = UIStackView(arrangedSubviews: [rightLabel, rightSubLabel])
|
||||||
|
rightVerticalStack.axis = .vertical
|
||||||
|
rightVerticalStack.alignment = .trailing
|
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
public required init?(coder aDecoder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - View Lifecycle
|
||||||
|
//-------------------------------------------------------
|
||||||
|
open override func updateView(_ size: CGFloat) {
|
||||||
|
super.updateView(size)
|
||||||
|
leftVerticalStack.updateView(size)
|
||||||
|
rightVerticalStack.updateView(size)
|
||||||
|
}
|
||||||
|
|
||||||
|
override open func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
contentView.addSubview(view)
|
||||||
|
containerHelper.constrainView(view)
|
||||||
|
|
||||||
|
leftVerticalStack.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
rightVerticalStack.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
rightLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
|
||||||
|
rightSubLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
|
||||||
|
view.addSubview(leftVerticalStack)
|
||||||
|
view.addSubview(rightVerticalStack)
|
||||||
|
NSLayoutConstraint.pinViews(leftView: leftVerticalStack, rightView: rightVerticalStack, alignTop: true)
|
||||||
|
|
||||||
|
leftHeadline.numberOfLines = 1
|
||||||
|
rightLabel.numberOfLines = 1
|
||||||
|
rightSubLabel.numberOfLines = 1
|
||||||
|
}
|
||||||
|
//----------------------------------------------------
|
||||||
|
// 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? ListTwoColumnPriceDescriptionModel else { return }
|
||||||
|
leftHeadline.set(with: model.leftHeadline, delegateObject, additionalData)
|
||||||
|
leftBody.set(with: model.leftBody, delegateObject, additionalData)
|
||||||
|
rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
|
||||||
|
rightSubLabel.set(with: model.rightSubLabel, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override class func estimatedHeight(with molecule: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
return 80
|
||||||
|
}
|
||||||
|
|
||||||
|
override open func reset() {
|
||||||
|
super.reset()
|
||||||
|
leftVerticalStack.reset()
|
||||||
|
rightVerticalStack.reset()
|
||||||
|
leftHeadline.styleB1(true)
|
||||||
|
leftBody.styleB2(true)
|
||||||
|
rightLabel.styleB2(true)
|
||||||
|
rightSubLabel.styleB2(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
//
|
||||||
|
// ListTwoColumnPriceDescriptionModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kruthika KP on 26/02/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class ListTwoColumnPriceDescriptionModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "list2CTxtPrc1"
|
||||||
|
public var leftHeadline: LabelModel
|
||||||
|
public var leftBody: LabelModel
|
||||||
|
public var rightLabel: LabelModel
|
||||||
|
public var rightSubLabel: LabelModel
|
||||||
|
|
||||||
|
override public func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
|
rightLabel.hero = 0
|
||||||
|
if rightSubLabel.textColor == nil {
|
||||||
|
rightSubLabel.textColor = Color(uiColor: .mvmCoolGray6)
|
||||||
|
}
|
||||||
|
if rightSubLabel.attributes == nil {
|
||||||
|
rightSubLabel.attributes = [LabelAttributeStrikeThroughModel(0, rightSubLabel.text.count)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(leftHeadline: LabelModel,leftBody: LabelModel, rightLabel: LabelModel, rightSubLabel: LabelModel) {
|
||||||
|
self.leftHeadline = leftHeadline
|
||||||
|
self.leftBody = leftBody
|
||||||
|
self.rightLabel = rightLabel
|
||||||
|
self.rightSubLabel = rightSubLabel
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case leftHeadline
|
||||||
|
case leftBody
|
||||||
|
case rightLabel
|
||||||
|
case rightSubLabel
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
leftHeadline = try typeContainer.decode(LabelModel.self, forKey: .leftHeadline)
|
||||||
|
leftBody = try typeContainer.decode(LabelModel.self, forKey: .leftBody)
|
||||||
|
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
|
||||||
|
rightSubLabel = try typeContainer.decode(LabelModel.self, forKey: .rightSubLabel)
|
||||||
|
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(leftHeadline, forKey: .leftHeadline)
|
||||||
|
try container.encode(leftBody, forKey: .leftBody)
|
||||||
|
try container.encode(rightLabel, forKey: .rightLabel)
|
||||||
|
try container.encode(rightSubLabel, forKey: .rightSubLabel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// ListTwoColumnPriceDetails.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 19/02/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objcMembers open class ListTwoColumnPriceDetails: TableViewCell {
|
||||||
|
|
||||||
|
let leftLabel = Label.commonLabelB2(true)
|
||||||
|
let rightLabel = Label.commonLabelB2(true)
|
||||||
|
let view = MVMCoreUICommonViewsUtility.commonView()
|
||||||
|
|
||||||
|
// MARK: - MFViewProtocol
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
view.addSubview(leftLabel)
|
||||||
|
view.addSubview(rightLabel)
|
||||||
|
NSLayoutConstraint.pinViews(leftView: leftLabel, rightView: rightLabel, alignTop: true)
|
||||||
|
contentView.addSubview(view)
|
||||||
|
containerHelper.constrainView(view)
|
||||||
|
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
|
||||||
|
rightLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func updateView(_ size: CGFloat) {
|
||||||
|
super.updateView(size)
|
||||||
|
leftLabel.updateView(size)
|
||||||
|
rightLabel.updateView(size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - MoleculeViewProtocol
|
||||||
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
guard let model = model as? ListTwoColumnPriceDetailsModel else { return }
|
||||||
|
leftLabel.set(with: model.leftLabel, delegateObject, additionalData)
|
||||||
|
rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func reset() {
|
||||||
|
super.reset()
|
||||||
|
leftLabel.reset()
|
||||||
|
rightLabel.reset()
|
||||||
|
leftLabel.styleB2(true)
|
||||||
|
rightLabel.styleB2(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||||
|
return 15
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// ListTwoColumnPriceDetailsModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 19/02/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class ListTwoColumnPriceDetailsModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "list2CTxtPrc2"
|
||||||
|
public var leftLabel: LabelModel
|
||||||
|
public var rightLabel: LabelModel
|
||||||
|
|
||||||
|
public init(leftLabel: LabelModel, rightLabel:LabelModel) {
|
||||||
|
self.leftLabel = leftLabel
|
||||||
|
self.rightLabel = rightLabel
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defaults to set
|
||||||
|
override public func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
|
style = "none"
|
||||||
|
if leftLabel.textColor == nil {
|
||||||
|
leftLabel.textColor = Color(uiColor: .mvmCoolGray6)
|
||||||
|
}
|
||||||
|
if rightLabel.textColor == nil {
|
||||||
|
rightLabel.textColor = Color(uiColor: .mvmCoolGray6)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case leftLabel
|
||||||
|
case rightLabel
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel)
|
||||||
|
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
|
||||||
|
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(leftLabel, forKey: .leftLabel)
|
||||||
|
try container.encode(rightLabel, forKey: .rightLabel)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -44,7 +44,7 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
// MARK: - ModelMoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
@ -59,7 +59,7 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
override open func reset() {
|
override open func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
@ -38,7 +38,7 @@ import Foundation
|
|||||||
stack.restack()
|
stack.restack()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - ModelMoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
guard let model = model as? ListFourColumnDataUsageDividerModel else { return }
|
guard let model = model as? ListFourColumnDataUsageDividerModel else { return }
|
||||||
@ -52,7 +52,7 @@ import Foundation
|
|||||||
return 121
|
return 121
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
label1.styleBoldBodySmall(true)
|
label1.styleBoldBodySmall(true)
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// ListOneColumnFullWidthTextDividerSubsection.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Dhamodaram Nandi on 09/03/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
@objcMembers open class ListOneColumnFullWidthTextDividerSubsection: TableViewCell {
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Outlets
|
||||||
|
//-----------------------------------------------------
|
||||||
|
public var stack: Stack<StackModel>
|
||||||
|
public let headline = Label.commonLabelB1(true)
|
||||||
|
public let body = Label.commonLabelB2(true)
|
||||||
|
|
||||||
|
// MARK: - Initializers
|
||||||
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
stack = Stack<StackModel>.createStack(with: [(view: headline, model: StackItemModel(horizontalAlignment: .leading)),
|
||||||
|
(view: body, model: StackItemModel(spacing: 0, horizontalAlignment: .leading))],
|
||||||
|
axis: .vertical)
|
||||||
|
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)
|
||||||
|
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? ListOneColumnFullWidthTextDividerSubsectionModel else { return }
|
||||||
|
headline.set(with: model.headline, delegateObject, additionalData)
|
||||||
|
body.set(with: model.body, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
return 90
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func reset() {
|
||||||
|
super.reset()
|
||||||
|
headline.styleB1(true)
|
||||||
|
body.styleB2(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user