merge from feature/coding
This commit is contained in:
commit
085aa62c8b
@ -92,8 +92,10 @@
|
||||
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B392398524F0067DD0F /* Toggle.swift */; };
|
||||
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; };
|
||||
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; };
|
||||
0ACDF26723D9F177002044B2 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ACDF26623D9F177002044B2 /* EntryFieldContainer.swift */; };
|
||||
0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; };
|
||||
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; };
|
||||
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; };
|
||||
9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; };
|
||||
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; };
|
||||
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; };
|
||||
9445890C2385BCE300DE9FD4 /* ProgressBarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */; };
|
||||
@ -398,9 +400,11 @@
|
||||
0AA33B392398524F0067DD0F /* Toggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toggle.swift; sourceTree = "<group>"; };
|
||||
0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = "<group>"; };
|
||||
0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = "<group>"; };
|
||||
0ACDF26623D9F177002044B2 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = "<group>"; };
|
||||
0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
|
||||
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = "<group>"; };
|
||||
31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = "<group>"; };
|
||||
9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = "<group>"; };
|
||||
9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = "<group>"; };
|
||||
943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = "<group>"; };
|
||||
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = "<group>"; };
|
||||
9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBarModel.swift; sourceTree = "<group>"; };
|
||||
@ -707,7 +711,7 @@
|
||||
0ABD1369237B18EE0081388D /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0ACDF26623D9F177002044B2 /* EntryFieldContainer.swift */,
|
||||
9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */,
|
||||
D29E28DE23D740FC00ACEA85 /* Container */,
|
||||
014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */,
|
||||
D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */,
|
||||
@ -1169,7 +1173,9 @@
|
||||
D213347623843825008E41B3 /* Line.swift */,
|
||||
DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */,
|
||||
94C2D9822386F3E30006CF46 /* Label */,
|
||||
31BE15CA23D8924C00452370 /* CheckboxModel.swift */,
|
||||
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */,
|
||||
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */,
|
||||
0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */,
|
||||
01004F2F22721C3800991ECC /* RadioButton.swift */,
|
||||
D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */,
|
||||
@ -1507,9 +1513,9 @@
|
||||
files = (
|
||||
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
|
||||
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */,
|
||||
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */,
|
||||
94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */,
|
||||
D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */,
|
||||
0ACDF26723D9F177002044B2 /* EntryFieldContainer.swift in Sources */,
|
||||
D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */,
|
||||
DBC4391822442197001AB423 /* CaretView.swift in Sources */,
|
||||
C07065C42395677300FBF997 /* Link.swift in Sources */,
|
||||
@ -1597,6 +1603,7 @@
|
||||
D2D6CD4022E78C1A00D701B8 /* Scroller.swift in Sources */,
|
||||
0A7EF85F23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift in Sources */,
|
||||
01509D952327ED1900EF99AA /* HeadlineBodyTextButtonSwitch.swift in Sources */,
|
||||
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */,
|
||||
D260105523CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift in Sources */,
|
||||
D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */,
|
||||
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */,
|
||||
@ -1683,6 +1690,7 @@
|
||||
D28A839323CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift in Sources */,
|
||||
D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */,
|
||||
D260105F23D0BFFC00764D80 /* StackItem.swift in Sources */,
|
||||
9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */,
|
||||
01EB369323609801006832FA /* HeaderModel.swift in Sources */,
|
||||
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */,
|
||||
0A21DB83235DFBC500C160A2 /* MdnEntryField.swift in Sources */,
|
||||
|
||||
@ -76,6 +76,27 @@ import MVMCore
|
||||
}
|
||||
}
|
||||
|
||||
open override var isEnabled: Bool {
|
||||
didSet {
|
||||
|
||||
isUserInteractionEnabled = isEnabled
|
||||
|
||||
if isEnabled {
|
||||
layer.borderColor = borderColor.cgColor
|
||||
backgroundColor = isSelected ? checkedBackgroundColor : unCheckedBackgroundColor
|
||||
setShapeLayerStrokeColor(checkColor)
|
||||
} else {
|
||||
layer.borderColor = disabledBorderColor.cgColor
|
||||
backgroundColor = disabledBackgroundColor
|
||||
setShapeLayerStrokeColor(disabledCheckColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var disabledBackgroundColor: UIColor = .clear
|
||||
public var disabledBorderColor: UIColor = .mvmCoolGray3
|
||||
public var disabledCheckColor: UIColor = .mvmCoolGray3
|
||||
|
||||
/// Color of the check mark.
|
||||
public var checkColor: UIColor = .black {
|
||||
didSet {
|
||||
@ -107,7 +128,6 @@ import MVMCore
|
||||
if !updateSelectionOnly {
|
||||
layoutIfNeeded()
|
||||
shapeLayer?.removeAllAnimations()
|
||||
|
||||
updateCheckboxUI(isSelected: isSelected, isAnimated: isAnimated)
|
||||
FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol)
|
||||
updateAccessibilityLabel()
|
||||
@ -154,16 +174,12 @@ import MVMCore
|
||||
|
||||
public convenience init(isChecked: Bool) {
|
||||
self.init(frame: .zero)
|
||||
updateSelectionOnly = true
|
||||
isSelected = isChecked
|
||||
updateSelectionOnly = false
|
||||
checkAndBypassAnimations(selected: isChecked)
|
||||
}
|
||||
|
||||
public convenience init(checkedBackgroundColor: UIColor, unCheckedBackgroundColor: UIColor, isChecked: Bool = false) {
|
||||
self.init(frame: .zero)
|
||||
updateSelectionOnly = true
|
||||
isSelected = isChecked
|
||||
updateSelectionOnly = false
|
||||
checkAndBypassAnimations(selected: isChecked)
|
||||
self.checkedBackgroundColor = checkedBackgroundColor
|
||||
self.unCheckedBackgroundColor = unCheckedBackgroundColor
|
||||
}
|
||||
@ -177,8 +193,6 @@ import MVMCore
|
||||
|
||||
drawShapeLayer()
|
||||
layer.cornerRadius = isRound ? cornerRadiusValue : 0
|
||||
layer.borderWidth = borderWidth
|
||||
layer.borderColor = borderColor.cgColor
|
||||
}
|
||||
|
||||
open override func setupView() {
|
||||
@ -228,7 +242,7 @@ import MVMCore
|
||||
self.shapeLayer = shapeLayer
|
||||
shapeLayer.frame = bounds
|
||||
layer.addSublayer(shapeLayer)
|
||||
shapeLayer.strokeColor = checkColor.cgColor
|
||||
shapeLayer.strokeColor = isEnabled ? checkColor.cgColor : disabledCheckColor.cgColor
|
||||
shapeLayer.fillColor = UIColor.clear.cgColor
|
||||
shapeLayer.path = checkMarkPath()
|
||||
shapeLayer.lineJoin = .miter
|
||||
@ -268,9 +282,7 @@ import MVMCore
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
self.updateSelectionOnly = true
|
||||
self.isSelected = selected
|
||||
self.updateSelectionOnly = false
|
||||
self.checkAndBypassAnimations(selected: selected)
|
||||
self.drawShapeLayer()
|
||||
self.shapeLayer?.removeAllAnimations()
|
||||
self.updateCheckboxUI(isSelected: selected, isAnimated: animated)
|
||||
@ -313,23 +325,6 @@ import MVMCore
|
||||
}
|
||||
}
|
||||
|
||||
func isEnabled(_ enabled: Bool) {
|
||||
|
||||
isUserInteractionEnabled = enabled
|
||||
|
||||
if enabled {
|
||||
layer.borderColor = borderColor.cgColor
|
||||
backgroundColor = isSelected ? checkedBackgroundColor : unCheckedBackgroundColor
|
||||
alpha = 1.0
|
||||
setShapeLayerStrokeColor(checkColor)
|
||||
} else {
|
||||
layer.borderColor = UIColor.mfSilver().cgColor
|
||||
backgroundColor = .clear
|
||||
alpha = DisableOppacity
|
||||
setShapeLayerStrokeColor(UIColor.mfSilver())
|
||||
}
|
||||
}
|
||||
|
||||
private func setShapeLayerStrokeColor(_ color: UIColor) {
|
||||
|
||||
if let shapeLayer = shapeLayer {
|
||||
@ -345,13 +340,19 @@ import MVMCore
|
||||
widthConstraint?.isActive = isActive
|
||||
}
|
||||
|
||||
private func checkAndBypassAnimations(selected: Bool) {
|
||||
updateSelectionOnly = true
|
||||
isSelected = selected
|
||||
updateSelectionOnly = false
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - UITouch
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
|
||||
sendActions(for: .touchUpInside)
|
||||
sendActions(for: .touchUpInside)
|
||||
}
|
||||
|
||||
override open func accessibilityActivate() -> Bool {
|
||||
@ -370,7 +371,7 @@ import MVMCore
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
|
||||
isEnabled(true)
|
||||
isEnabled = true
|
||||
shapeLayer?.removeAllAnimations()
|
||||
shapeLayer?.removeFromSuperlayer()
|
||||
shapeLayer = nil
|
||||
@ -379,9 +380,7 @@ import MVMCore
|
||||
borderWidth = 1.0
|
||||
checkColor = .black
|
||||
checkWidth = 2.0
|
||||
updateSelectionOnly = true
|
||||
isSelected = false
|
||||
updateSelectionOnly = false
|
||||
checkAndBypassAnimations(selected: false)
|
||||
}
|
||||
|
||||
open func setAsMolecule() {
|
||||
@ -424,16 +423,14 @@ import MVMCore
|
||||
layer.borderWidth = borderWidth
|
||||
}
|
||||
|
||||
if let isChecked = dictionary["isChecked"] as? Bool, isChecked {
|
||||
updateSelectionOnly = true
|
||||
isSelected = isChecked
|
||||
updateSelectionOnly = false
|
||||
}
|
||||
|
||||
if let checkColorHex = dictionary["checkColor"] as? String {
|
||||
checkColor = UIColor.mfGet(forHex: checkColorHex)
|
||||
}
|
||||
|
||||
if let isChecked = dictionary["isChecked"] as? Bool, isChecked {
|
||||
checkAndBypassAnimations(selected: isChecked)
|
||||
}
|
||||
|
||||
if let unCheckedBackgroundColorHex = dictionary["unCheckedBackgroundColor"] as? String {
|
||||
unCheckedBackgroundColor = UIColor.mfGet(forHex: unCheckedBackgroundColorHex)
|
||||
}
|
||||
@ -451,13 +448,57 @@ import MVMCore
|
||||
}
|
||||
|
||||
if let enabled = dictionary["isEnabled"] as? Bool {
|
||||
isEnabled(enabled)
|
||||
isEnabled = enabled
|
||||
}
|
||||
|
||||
if let actionMap = dictionary.optionalDictionaryForKey("action") {
|
||||
actionBlock = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) }
|
||||
}
|
||||
}
|
||||
|
||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
|
||||
guard let model = model as? CheckboxModel else { return }
|
||||
|
||||
self.delegateObject = delegateObject
|
||||
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
|
||||
|
||||
groupName = model.groupName
|
||||
fieldValue = model.value
|
||||
isRequired = model.required
|
||||
|
||||
if let fieldKey = model.fieldKey {
|
||||
self.fieldKey = fieldKey
|
||||
}
|
||||
|
||||
borderColor = model.borderColor.uiColor
|
||||
borderWidth = model.borderWidth
|
||||
|
||||
checkColor = model.checkColor.uiColor
|
||||
unCheckedBackgroundColor = model.unCheckedBackgroundColor.uiColor
|
||||
checkedBackgroundColor = model.checkedBackgroundColor.uiColor
|
||||
disabledCheckColor = model.disabledCheckColor.uiColor
|
||||
disabledBorderColor = model.disabledBorderColor.uiColor
|
||||
disabledBackgroundColor = model.disabledBackgroundColor.uiColor
|
||||
|
||||
isAnimated = model.isAnimated
|
||||
isRound = model.isRound
|
||||
|
||||
if model.isChecked {
|
||||
checkAndBypassAnimations(selected: model.isChecked)
|
||||
}
|
||||
|
||||
isEnabled = model.isEnabled
|
||||
|
||||
if let action = model.action {
|
||||
actionBlock = {
|
||||
if let actionMap = action.toJSON() {
|
||||
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK:- FormValidationProtocol
|
||||
|
||||
24
MVMCoreUI/Atoms/Views/CheckboxLabelModel.swift
Normal file
24
MVMCoreUI/Atoms/Views/CheckboxLabelModel.swift
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// CheckboxWithLabelViewModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Chintakrinda, Arun Kumar (Arun) on 21/01/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum CheckboxPosition: String, Codable {
|
||||
case center
|
||||
case top
|
||||
case bottom
|
||||
}
|
||||
|
||||
@objcMembers public class CheckboxLabelModel: MoleculeModelProtocol {
|
||||
public static var identifier: String = "checkboxLabel"
|
||||
public var backgroundColor: Color?
|
||||
|
||||
public var checkboxAlignment: CheckboxPosition?
|
||||
public var checkbox: CheckboxModel
|
||||
public var label: LabelModel
|
||||
}
|
||||
106
MVMCoreUI/Atoms/Views/CheckboxModel.swift
Normal file
106
MVMCoreUI/Atoms/Views/CheckboxModel.swift
Normal file
@ -0,0 +1,106 @@
|
||||
//
|
||||
// CheckboxModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Chintakrinda, Arun Kumar (Arun) on 21/01/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class CheckboxModel: MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "checkbox"
|
||||
public var backgroundColor: Color?
|
||||
|
||||
public var groupName: String?
|
||||
public var value: String?
|
||||
public var fieldKey: String?
|
||||
public var required: Bool = false
|
||||
public var borderColor: Color = Color(uiColor: .black)
|
||||
public var borderWidth: CGFloat = 1
|
||||
public var isChecked: Bool = false
|
||||
public var checkColor: Color = Color(uiColor: .black)
|
||||
public var unCheckedBackgroundColor: Color = Color(uiColor: .clear)
|
||||
public var checkedBackgroundColor: Color = Color(uiColor: .clear)
|
||||
public var isAnimated: Bool = true
|
||||
public var isRound: Bool = false
|
||||
public var isEnabled: Bool = true
|
||||
public var action: ActionModelProtocol?
|
||||
public var disabledBackgroundColor: Color = Color(uiColor: .clear)
|
||||
public var disabledBorderColor: Color = Color(uiColor: .mvmCoolGray3)
|
||||
public var disabledCheckColor: Color = Color(uiColor: .mvmCoolGray3)
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case groupName
|
||||
case value
|
||||
case fieldKey
|
||||
case required
|
||||
case borderColor
|
||||
case borderWidth
|
||||
case isChecked
|
||||
case checkColor
|
||||
case unCheckedBackgroundColor
|
||||
case checkedBackgroundColor
|
||||
case disabledBackgroundColor
|
||||
case disabledCheckColor
|
||||
case disabledBorderColor
|
||||
case isAnimated
|
||||
case isRound
|
||||
case isEnabled
|
||||
case action
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName)
|
||||
value = try typeContainer.decodeIfPresent(String.self, forKey: .value)
|
||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||
required = try typeContainer.decodeIfPresent(Bool.self, forKey: .required) ?? false
|
||||
borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) ?? 1
|
||||
borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) ?? Color(uiColor: .black)
|
||||
checkColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkColor) ?? Color(uiColor: .black)
|
||||
unCheckedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .unCheckedBackgroundColor) ?? Color(uiColor: .clear)
|
||||
checkedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkedBackgroundColor) ?? Color(uiColor: .clear)
|
||||
disabledBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBackgroundColor) ?? Color(uiColor: .clear)
|
||||
disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor) ?? Color(uiColor: .mvmCoolGray3)
|
||||
disabledCheckColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledCheckColor) ?? Color(uiColor: .mvmCoolGray3)
|
||||
isChecked = try typeContainer.decodeIfPresent(Bool.self, forKey: .isChecked) ?? false
|
||||
isAnimated = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAnimated) ?? true
|
||||
isRound = try typeContainer.decodeIfPresent(Bool.self, forKey: .isRound) ?? false
|
||||
isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEnabled) ?? true
|
||||
action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||
try container.encodeIfPresent(value, forKey: .value)
|
||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||
try container.encodeIfPresent(required, forKey: .required)
|
||||
try container.encodeIfPresent(borderColor, forKey: .borderColor)
|
||||
try container.encode(borderWidth, forKey: .borderWidth)
|
||||
try container.encode(isChecked, forKey: .isChecked)
|
||||
try container.encodeIfPresent(checkColor, forKey: .checkColor)
|
||||
try container.encodeIfPresent(unCheckedBackgroundColor, forKey: .unCheckedBackgroundColor)
|
||||
try container.encodeIfPresent(checkedBackgroundColor, forKey: .checkedBackgroundColor)
|
||||
try container.encodeIfPresent(disabledBorderColor, forKey: .disabledBorderColor)
|
||||
try container.encodeIfPresent(disabledBackgroundColor, forKey: .disabledBackgroundColor)
|
||||
try container.encodeIfPresent(disabledCheckColor, forKey: .disabledCheckColor)
|
||||
try container.encodeIfPresent(isAnimated, forKey: .isAnimated)
|
||||
try container.encodeIfPresent(isRound, forKey: .isRound)
|
||||
try container.encodeIfPresent(isEnabled, forKey: .isEnabled)
|
||||
try container.encodeModelIfPresent(action, forKey: .action)
|
||||
}
|
||||
}
|
||||
@ -21,12 +21,6 @@
|
||||
|
||||
public var checkboxPosition: CheckboxPosition = .center
|
||||
|
||||
public enum CheckboxPosition: String {
|
||||
case center
|
||||
case top
|
||||
case bottom
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Constraints
|
||||
//--------------------------------------------------
|
||||
@ -120,6 +114,17 @@
|
||||
checkboxCenterYConstraint?.isActive = false
|
||||
}
|
||||
}
|
||||
|
||||
open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
guard let checkBoxWithLabelModel = model as? CheckboxLabelModel else { return }
|
||||
|
||||
if let checkboxAlignment = checkBoxWithLabelModel.checkboxAlignment {
|
||||
alignCheckbox(checkboxAlignment)
|
||||
}
|
||||
|
||||
checkbox.setWithModel(checkBoxWithLabelModel.checkbox, delegateObject, additionalData)
|
||||
label.setWithModel(checkBoxWithLabelModel.label, delegateObject, additionalData)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Molecular
|
||||
|
||||
@ -19,6 +19,9 @@ open class DashLine: View {
|
||||
get { return model as? DashLineModel }
|
||||
}
|
||||
|
||||
//TODO: Need this for BAU. Can remove once we fix BAU
|
||||
public var dashColor: UIColor?
|
||||
|
||||
@objc private var dashLayer: CAShapeLayer?
|
||||
|
||||
//------------------------------------------------------
|
||||
@ -68,7 +71,7 @@ open class DashLine: View {
|
||||
dashLayer.lineCap = .round
|
||||
dashLayer.lineDashPattern = [NSNumber(value: 2), NSNumber(value: 2)]
|
||||
dashLayer.path = path.cgPath
|
||||
dashLayer.strokeColor = dashModel?.dashColor.cgColor
|
||||
dashLayer.strokeColor = dashModel?.dashColor.cgColor ?? dashColor?.cgColor
|
||||
dashLayer.fillColor = UIColor.clear.cgColor
|
||||
dashLayer.backgroundColor = backgroundColor?.cgColor ?? UIColor.white.cgColor
|
||||
self.dashLayer = dashLayer
|
||||
|
||||
@ -315,7 +315,7 @@ public typealias ActionBlock = () -> ()
|
||||
}
|
||||
case let actionAtt as LabelAttributeActionModel:
|
||||
addTappableLinkAttribute(range: NSRange(location: range.location, length: range.length)) {
|
||||
if let data = try? actionAtt.encode(using: JSONEncoder()), let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any] {
|
||||
if let data = try? actionAtt.action.encode(using: JSONEncoder()), let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any] {
|
||||
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,7 +43,9 @@ import UIKit
|
||||
public static var identifier: String = "line"
|
||||
public var type: Style = .standard
|
||||
public var frequency: Frequency? = .allExceptTop
|
||||
public var color: Color?
|
||||
|
||||
//TODO: use color insted of backgroundColor. Needs server changes
|
||||
// public var color: Color?
|
||||
public var backgroundColor: Color?
|
||||
|
||||
public init(type: Style) {
|
||||
@ -66,7 +68,7 @@ import UIKit
|
||||
if let frequency = try typeContainer.decodeIfPresent(Frequency.self, forKey: .frequency) {
|
||||
self.frequency = frequency
|
||||
}
|
||||
color = try typeContainer.decodeIfPresent(Color.self, forKey: .color)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@ -74,6 +76,6 @@ import UIKit
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(type, forKey: .type)
|
||||
try container.encodeIfPresent(frequency, forKey: .frequency)
|
||||
try container.encodeIfPresent(color, forKey: .color)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,293 +0,0 @@
|
||||
//
|
||||
// EntryFieldContainer.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Kevin Christiano on 11/12/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
@objcMembers open class EntryFieldContainer: View {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Drawing Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
/// The bottom border line. Height is dynamic based on scenario.
|
||||
public var bottomBar: CAShapeLayer? = {
|
||||
let layer = CAShapeLayer()
|
||||
layer.backgroundColor = UIColor.black.cgColor
|
||||
layer.drawsAsynchronously = true
|
||||
layer.anchorPoint = CGPoint(x: 0.5, y: 1.0);
|
||||
return layer
|
||||
}()
|
||||
|
||||
/// Total control over the drawn top, bottom, left and right borders.
|
||||
public var disableAllBorders = false {
|
||||
didSet {
|
||||
bottomBar?.isHidden = disableAllBorders
|
||||
}
|
||||
}
|
||||
|
||||
private(set) var fieldState: FieldState = .original {
|
||||
didSet (oldState) {
|
||||
// Will not update if new state is the same as old.
|
||||
if fieldState != oldState {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.fieldState.setStateUI(for: self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines if the top, left, and right borders should be drawn.
|
||||
private var hideBorders = false
|
||||
|
||||
public var borderStrokeColor: UIColor = .mfSilver()
|
||||
private var borderPath: UIBezierPath = UIBezierPath()
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Property Observers
|
||||
//--------------------------------------------------
|
||||
|
||||
private var _isEnabled: Bool = true
|
||||
private var _showError: Bool = false
|
||||
private var _isLocked: Bool = false
|
||||
private var _isSelected: Bool = false
|
||||
|
||||
public var isEnabled: Bool {
|
||||
get { return _isEnabled }
|
||||
set (enabled) {
|
||||
|
||||
_isEnabled = enabled
|
||||
_isLocked = false
|
||||
_isSelected = false
|
||||
_showError = false
|
||||
|
||||
fieldState = enabled ? .original : .disabled
|
||||
}
|
||||
}
|
||||
|
||||
public var showError: Bool {
|
||||
get { return _showError }
|
||||
set (error) {
|
||||
|
||||
_showError = error
|
||||
_isEnabled = true
|
||||
_isLocked = false
|
||||
_isSelected = false
|
||||
|
||||
fieldState = error ? .error : .original
|
||||
}
|
||||
}
|
||||
|
||||
public var isLocked: Bool {
|
||||
get { return _isLocked }
|
||||
set (locked) {
|
||||
|
||||
_isLocked = locked
|
||||
_isEnabled = true
|
||||
_isSelected = false
|
||||
_showError = false
|
||||
|
||||
fieldState = locked ? .locked : .original
|
||||
}
|
||||
}
|
||||
|
||||
public var isSelected: Bool {
|
||||
get { return _isSelected }
|
||||
set (selected) {
|
||||
|
||||
_isSelected = selected
|
||||
_isLocked = false
|
||||
_isEnabled = true
|
||||
|
||||
if _showError {
|
||||
fieldState = selected ? .selectedError : .error
|
||||
} else {
|
||||
fieldState = selected ? .selected : .original
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Delegate
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Holds reference to delegateObject to inform molecular tableView of an update.
|
||||
var delegateObject: MVMCoreUIDelegateObject?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
refreshUI(bottomBarSize: showError ? 4 : 1)
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
|
||||
refreshUI()
|
||||
}
|
||||
|
||||
/// This handles the top, left, and right border lines.
|
||||
open override func draw(_ rect: CGRect) {
|
||||
super.draw(rect)
|
||||
|
||||
borderPath.removeAllPoints()
|
||||
|
||||
if !disableAllBorders && !hideBorders {
|
||||
// Brings the other half of the line inside the view to prevent cropping.
|
||||
let origin = bounds.origin
|
||||
let size = frame.size
|
||||
let insetLean: CGFloat = 0.5
|
||||
borderPath.lineWidth = 1
|
||||
|
||||
borderPath.move(to: CGPoint(x: origin.x + insetLean, y: origin.y + size.height))
|
||||
borderPath.addLine(to: CGPoint(x: origin.x + insetLean, y: origin.y + insetLean))
|
||||
borderPath.addLine(to: CGPoint(x: origin.x + size.width - insetLean, y: origin.y + insetLean))
|
||||
borderPath.addLine(to: CGPoint(x: origin.x + size.width - insetLean, y: origin.y + size.height))
|
||||
|
||||
borderStrokeColor.setStroke()
|
||||
borderPath.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
override open func setupView() {
|
||||
super.setupView()
|
||||
|
||||
isAccessibilityElement = false
|
||||
isOpaque = false
|
||||
|
||||
if let bottomBar = bottomBar {
|
||||
layer.addSublayer(bottomBar)
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Draw States
|
||||
//--------------------------------------------------
|
||||
|
||||
public enum FieldState {
|
||||
case original
|
||||
case error
|
||||
case selectedError
|
||||
case selected
|
||||
case locked
|
||||
case disabled
|
||||
|
||||
public func setStateUI(for formField: EntryFieldContainer) {
|
||||
|
||||
switch self {
|
||||
case .original:
|
||||
formField.originalUI()
|
||||
|
||||
case .error:
|
||||
formField.errorUI()
|
||||
|
||||
case .selectedError:
|
||||
formField.selectedErrorUI()
|
||||
|
||||
case .selected:
|
||||
formField.selectedUI()
|
||||
|
||||
case .locked:
|
||||
formField.lockedUI()
|
||||
|
||||
case .disabled:
|
||||
formField.disabledUI()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open func originalUI() {
|
||||
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = false
|
||||
borderStrokeColor = .mfSilver()
|
||||
bottomBar?.backgroundColor = UIColor.black.cgColor
|
||||
refreshUI(bottomBarSize: 1)
|
||||
}
|
||||
|
||||
open func errorUI() {
|
||||
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = false
|
||||
borderStrokeColor = .mfPumpkin()
|
||||
bottomBar?.backgroundColor = UIColor.mfPumpkin().cgColor
|
||||
refreshUI(bottomBarSize: 4)
|
||||
}
|
||||
|
||||
open func selectedErrorUI() {
|
||||
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = false
|
||||
borderStrokeColor = .black
|
||||
bottomBar?.backgroundColor = UIColor.mfPumpkin().cgColor
|
||||
refreshUI(bottomBarSize: 4)
|
||||
}
|
||||
|
||||
open func selectedUI() {
|
||||
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = false
|
||||
borderStrokeColor = .black
|
||||
bottomBar?.backgroundColor = UIColor.black.cgColor
|
||||
refreshUI(bottomBarSize: 1)
|
||||
}
|
||||
|
||||
open func lockedUI() {
|
||||
|
||||
isUserInteractionEnabled = false
|
||||
hideBorders = true
|
||||
borderStrokeColor = .clear
|
||||
bottomBar?.backgroundColor = UIColor.clear.cgColor
|
||||
refreshUI(bottomBarSize: 1)
|
||||
}
|
||||
|
||||
open func disabledUI() {
|
||||
|
||||
isUserInteractionEnabled = false
|
||||
hideBorders = false
|
||||
borderStrokeColor = .mfSilver()
|
||||
bottomBar?.backgroundColor = UIColor.mfSilver().cgColor
|
||||
refreshUI(bottomBarSize: 1)
|
||||
}
|
||||
|
||||
open func refreshUI(bottomBarSize: CGFloat? = nil) {
|
||||
|
||||
if !disableAllBorders {
|
||||
let size: CGFloat = bottomBarSize ?? (showError ? 4 : 1)
|
||||
bottomBar?.frame = CGRect(x: 0, y: bounds.height - size, width: bounds.width, height: size)
|
||||
|
||||
delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self)
|
||||
setNeedsDisplay()
|
||||
layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
self.delegateObject = delegateObject
|
||||
}
|
||||
}
|
||||
|
||||
extension EntryFieldContainer {
|
||||
|
||||
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 }
|
||||
}
|
||||
}
|
||||
@ -1,293 +0,0 @@
|
||||
//
|
||||
// EntryFieldContainer.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Kevin Christiano on 11/12/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
@objcMembers open class EntryFieldContainer: View {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Drawing Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
/// The bottom border line. Height is dynamic based on scenario.
|
||||
public var bottomBar: CAShapeLayer? = {
|
||||
let layer = CAShapeLayer()
|
||||
layer.backgroundColor = UIColor.black.cgColor
|
||||
layer.drawsAsynchronously = true
|
||||
layer.anchorPoint = CGPoint(x: 0.5, y: 1.0);
|
||||
return layer
|
||||
}()
|
||||
|
||||
/// Total control over the drawn top, bottom, left and right borders.
|
||||
public var disableAllBorders = false {
|
||||
didSet {
|
||||
bottomBar?.isHidden = disableAllBorders
|
||||
}
|
||||
}
|
||||
|
||||
private(set) var fieldState: FieldState = .original {
|
||||
didSet (oldState) {
|
||||
// Will not update if new state is the same as old.
|
||||
if fieldState != oldState {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.fieldState.setStateUI(for: self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines if the top, left, and right borders should be drawn.
|
||||
private var hideBorders = false
|
||||
|
||||
public var borderStrokeColor: UIColor = .mfSilver()
|
||||
private var borderPath: UIBezierPath = UIBezierPath()
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Property Observers
|
||||
//--------------------------------------------------
|
||||
|
||||
private var _isEnabled: Bool = true
|
||||
private var _showError: Bool = false
|
||||
private var _isLocked: Bool = false
|
||||
private var _isSelected: Bool = false
|
||||
|
||||
public var isEnabled: Bool {
|
||||
get { return _isEnabled }
|
||||
set (enabled) {
|
||||
|
||||
_isEnabled = enabled
|
||||
_isLocked = false
|
||||
_isSelected = false
|
||||
_showError = false
|
||||
|
||||
fieldState = enabled ? .original : .disabled
|
||||
}
|
||||
}
|
||||
|
||||
public var showError: Bool {
|
||||
get { return _showError }
|
||||
set (error) {
|
||||
|
||||
_showError = error
|
||||
_isEnabled = true
|
||||
_isLocked = false
|
||||
_isSelected = false
|
||||
|
||||
fieldState = error ? .error : .original
|
||||
}
|
||||
}
|
||||
|
||||
public var isLocked: Bool {
|
||||
get { return _isLocked }
|
||||
set (locked) {
|
||||
|
||||
_isLocked = locked
|
||||
_isEnabled = true
|
||||
_isSelected = false
|
||||
_showError = false
|
||||
|
||||
fieldState = locked ? .locked : .original
|
||||
}
|
||||
}
|
||||
|
||||
public var isSelected: Bool {
|
||||
get { return _isSelected }
|
||||
set (selected) {
|
||||
|
||||
_isSelected = selected
|
||||
_isLocked = false
|
||||
_isEnabled = true
|
||||
|
||||
if _showError {
|
||||
fieldState = selected ? .selectedError : .error
|
||||
} else {
|
||||
fieldState = selected ? .selected : .original
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Delegate
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Holds reference to delegateObject to inform molecular tableView of an update.
|
||||
var delegateObject: MVMCoreUIDelegateObject?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
refreshUI(bottomBarSize: showError ? 4 : 1)
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
|
||||
refreshUI()
|
||||
}
|
||||
|
||||
/// This handles the top, left, and right border lines.
|
||||
open override func draw(_ rect: CGRect) {
|
||||
super.draw(rect)
|
||||
|
||||
borderPath.removeAllPoints()
|
||||
|
||||
if !disableAllBorders && !hideBorders {
|
||||
// Brings the other half of the line inside the view to prevent cropping.
|
||||
let origin = bounds.origin
|
||||
let size = frame.size
|
||||
let insetLean: CGFloat = 0.5
|
||||
borderPath.lineWidth = 1
|
||||
|
||||
borderPath.move(to: CGPoint(x: origin.x + insetLean, y: origin.y + size.height))
|
||||
borderPath.addLine(to: CGPoint(x: origin.x + insetLean, y: origin.y + insetLean))
|
||||
borderPath.addLine(to: CGPoint(x: origin.x + size.width - insetLean, y: origin.y + insetLean))
|
||||
borderPath.addLine(to: CGPoint(x: origin.x + size.width - insetLean, y: origin.y + size.height))
|
||||
|
||||
borderStrokeColor.setStroke()
|
||||
borderPath.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
override open func setupView() {
|
||||
super.setupView()
|
||||
|
||||
isAccessibilityElement = false
|
||||
isOpaque = false
|
||||
|
||||
if let bottomBar = bottomBar {
|
||||
layer.addSublayer(bottomBar)
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Draw States
|
||||
//--------------------------------------------------
|
||||
|
||||
public enum FieldState {
|
||||
case original
|
||||
case error
|
||||
case selectedError
|
||||
case selected
|
||||
case locked
|
||||
case disabled
|
||||
|
||||
public func setStateUI(for formField: EntryFieldContainer) {
|
||||
|
||||
switch self {
|
||||
case .original:
|
||||
formField.originalUI()
|
||||
|
||||
case .error:
|
||||
formField.errorUI()
|
||||
|
||||
case .selectedError:
|
||||
formField.selectedErrorUI()
|
||||
|
||||
case .selected:
|
||||
formField.selectedUI()
|
||||
|
||||
case .locked:
|
||||
formField.lockedUI()
|
||||
|
||||
case .disabled:
|
||||
formField.disabledUI()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open func originalUI() {
|
||||
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = false
|
||||
borderStrokeColor = .mfSilver()
|
||||
bottomBar?.backgroundColor = UIColor.black.cgColor
|
||||
refreshUI(bottomBarSize: 1)
|
||||
}
|
||||
|
||||
open func errorUI() {
|
||||
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = false
|
||||
borderStrokeColor = .mfPumpkin()
|
||||
bottomBar?.backgroundColor = UIColor.mfPumpkin().cgColor
|
||||
refreshUI(bottomBarSize: 4)
|
||||
}
|
||||
|
||||
open func selectedErrorUI() {
|
||||
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = false
|
||||
borderStrokeColor = .black
|
||||
bottomBar?.backgroundColor = UIColor.mfPumpkin().cgColor
|
||||
refreshUI(bottomBarSize: 4)
|
||||
}
|
||||
|
||||
open func selectedUI() {
|
||||
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = false
|
||||
borderStrokeColor = .black
|
||||
bottomBar?.backgroundColor = UIColor.black.cgColor
|
||||
refreshUI(bottomBarSize: 1)
|
||||
}
|
||||
|
||||
open func lockedUI() {
|
||||
|
||||
isUserInteractionEnabled = false
|
||||
hideBorders = true
|
||||
borderStrokeColor = .clear
|
||||
bottomBar?.backgroundColor = UIColor.clear.cgColor
|
||||
refreshUI(bottomBarSize: 1)
|
||||
}
|
||||
|
||||
open func disabledUI() {
|
||||
|
||||
isUserInteractionEnabled = false
|
||||
hideBorders = false
|
||||
borderStrokeColor = .mfSilver()
|
||||
bottomBar?.backgroundColor = UIColor.mfSilver().cgColor
|
||||
refreshUI(bottomBarSize: 1)
|
||||
}
|
||||
|
||||
open func refreshUI(bottomBarSize: CGFloat? = nil) {
|
||||
|
||||
if !disableAllBorders {
|
||||
let size: CGFloat = bottomBarSize ?? (showError ? 4 : 1)
|
||||
bottomBar?.frame = CGRect(x: 0, y: bounds.height - size, width: bounds.width, height: size)
|
||||
|
||||
delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self)
|
||||
setNeedsDisplay()
|
||||
layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
self.delegateObject = delegateObject
|
||||
}
|
||||
}
|
||||
|
||||
extension EntryFieldContainer {
|
||||
|
||||
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 }
|
||||
}
|
||||
}
|
||||
@ -137,6 +137,7 @@ import UIKit
|
||||
open func setupView() {
|
||||
selectionStyle = .none
|
||||
insetsLayoutMarginsFromSafeArea = false
|
||||
preservesSuperviewLayoutMargins = false
|
||||
contentView.insetsLayoutMarginsFromSafeArea = false
|
||||
contentView.preservesSuperviewLayoutMargins = false
|
||||
}
|
||||
|
||||
@ -7,13 +7,15 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@objcMembers public class HeadLineBodyCaretLinkImage: View {
|
||||
|
||||
@objcMembers public class HeadLineBodyCaretLinkImage: Container {
|
||||
let headlineBody = HeadlineBody(frame: .zero)
|
||||
let caretButton = CaretButton(frame: .zero)
|
||||
let backgroundImageView = MFLoadImageView()
|
||||
let backgroundImageView = MFLoadImageView(pinnedEdges: .all)
|
||||
var spaceBetweenConstant: CGFloat = 104.0
|
||||
let maxWidth : CGFloat = 350.0
|
||||
let maxWidth: CGFloat = 350.0
|
||||
static let heightConstant: CGFloat = 320.0
|
||||
var heightConstraint: NSLayoutConstraint?
|
||||
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
@ -29,25 +31,28 @@ import Foundation
|
||||
guard subviews.count == 0 else {
|
||||
return
|
||||
}
|
||||
let view = MVMCoreUICommonViewsUtility.commonView()
|
||||
addSubview(view)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: view)
|
||||
view.addSubview(headlineBody)
|
||||
view.addSubview(caretButton)
|
||||
heightConstraint = heightAnchor.constraint(equalToConstant: Self.heightConstant)
|
||||
heightConstraint?.isActive = true
|
||||
|
||||
let container = MVMCoreUICommonViewsUtility.commonView()
|
||||
addAndContain(container)
|
||||
|
||||
container.addSubview(headlineBody)
|
||||
container.addSubview(caretButton)
|
||||
|
||||
//Headline view
|
||||
headlineBody.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
|
||||
headlineBody.topAnchor.constraint(equalTo: view.topAnchor, constant: PaddingDefault).isActive = true
|
||||
headlineBody.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true
|
||||
headlineBody.topAnchor.constraint(equalTo: container.topAnchor, constant: 0).isActive = true
|
||||
|
||||
let headLineBodyWidth = headlineBody.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.85)
|
||||
let headLineBodyWidth = headlineBody.widthAnchor.constraint(equalTo: container.widthAnchor, multiplier: 0.85)
|
||||
headLineBodyWidth.priority = .defaultHigh
|
||||
headLineBodyWidth.isActive = true
|
||||
headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: maxWidth).isActive = true
|
||||
|
||||
//Caret view
|
||||
caretButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
caretButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
|
||||
view.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor, constant: PaddingDefault).isActive = true
|
||||
caretButton.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true
|
||||
container.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor, constant: 0).isActive = true
|
||||
|
||||
caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant).isActive = true
|
||||
|
||||
@ -56,9 +61,9 @@ import Foundation
|
||||
backgroundImageView.imageView.contentMode = .scaleAspectFill
|
||||
backgroundImageView.alignFillHorizontal()
|
||||
backgroundImageView.alignFillVertical()
|
||||
view.addSubview(backgroundImageView)
|
||||
addSubview(backgroundImageView)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: backgroundImageView)
|
||||
view.sendSubviewToBack(backgroundImageView)
|
||||
sendSubviewToBack(backgroundImageView)
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
@ -85,6 +90,7 @@ import Foundation
|
||||
guard let model = model as? HeadlineBodyCaretLinkImageModel else { return }
|
||||
headlineBody.setWithModel(model.headlineBody, delegateObject, additionalData)
|
||||
caretButton.setWithModel(model.caretLink, delegateObject, additionalData)
|
||||
caretButton.isHidden = model.caretLink == nil
|
||||
backgroundImageView.setWithModel(model.image, delegateObject, additionalData)
|
||||
backgroundImageView.alignFillHorizontal()
|
||||
backgroundImageView.alignFillVertical()
|
||||
|
||||
@ -8,10 +8,64 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
public class HeadlineBodyCaretLinkImageModel: MoleculeModelProtocol {
|
||||
public class HeadlineBodyCaretLinkImageModel: ContainerModel, MoleculeModelProtocol {
|
||||
public static var identifier: String = "headlineBodyCaretLinkImage"
|
||||
public var backgroundColor: Color?
|
||||
public var caretLink: CaretLinkModel?
|
||||
public var headlineBody: HeadlineBodyModel
|
||||
public var image: ImageViewModel
|
||||
|
||||
init(headlineBody: HeadlineBodyModel, image: ImageViewModel) {
|
||||
self.headlineBody = headlineBody
|
||||
self.image = image
|
||||
super.init()
|
||||
setDefaults()
|
||||
}
|
||||
|
||||
/// Defaults to set
|
||||
func setDefaults() {
|
||||
if useHorizontalMargins == nil {
|
||||
useHorizontalMargins = true
|
||||
}
|
||||
if useVerticalMargins == nil {
|
||||
useVerticalMargins = true
|
||||
}
|
||||
if topMarginPadding == nil {
|
||||
topMarginPadding = PaddingDefault
|
||||
}
|
||||
if bottomMarginPadding == nil {
|
||||
bottomMarginPadding = PaddingDefault
|
||||
}
|
||||
if image.height == nil {
|
||||
image.height = HeadLineBodyCaretLinkImage.heightConstant
|
||||
}
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case headlineBody
|
||||
case image
|
||||
case caretLink
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody)
|
||||
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
||||
caretLink = try typeContainer.decodeIfPresent(CaretLinkModel.self, forKey: .caretLink)
|
||||
try super.init(from: decoder)
|
||||
setDefaults()
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(HeadlineBodyCaretLinkImageModel.identifier, forKey: .moleculeName)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encode(headlineBody, forKey: .headlineBody)
|
||||
try container.encode(image, forKey: .image)
|
||||
try container.encodeIfPresent(caretLink, forKey: .caretLink)
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,6 +49,8 @@ import Foundation
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Line.self, viewModelClass: LineModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: GraphView.self, viewModelClass: CircleProgressModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CheckboxWithLabelView.self, viewModelClass: CheckboxLabelModel.self)
|
||||
|
||||
// Horizontal Combination Molecules
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self)
|
||||
|
||||
@ -60,28 +60,18 @@ extension NSLayoutConstraint.Axis: RawRepresentable {
|
||||
}
|
||||
}
|
||||
|
||||
@propertyWrapper
|
||||
public struct Axis {
|
||||
public var wrappedValue: NSLayoutConstraint.Axis
|
||||
|
||||
public init(wrappedValue value: NSLayoutConstraint.Axis) {
|
||||
self.wrappedValue = value
|
||||
}
|
||||
}
|
||||
|
||||
extension Axis: Codable {
|
||||
extension NSLayoutConstraint.Axis: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.singleValueContainer()
|
||||
let string = try typeContainer.decode(String.self)
|
||||
guard let axis = NSLayoutConstraint.Axis(rawValue: string) else {
|
||||
throw AxisError.notAnAxis
|
||||
}
|
||||
wrappedValue = axis
|
||||
self = axis
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
let string = wrappedValue.rawValueString
|
||||
var container = encoder.singleValueContainer()
|
||||
try container.encode(string)
|
||||
try container.encode(rawValueString)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user