diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 1c561bdd..f395d21b 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -84,10 +84,12 @@ 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; }; 0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; }; 0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B392398524F0067DD0F /* Toggle.swift */; }; - 0ABD136B237B193A0081388D /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136A237B193A0081388D /* EntryFieldContainer.swift */; }; 0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; }; 0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; }; + 0ACDF26B23DA0AC2002044B2 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ACDF26A23DA0AC2002044B2 /* 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 */; }; 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 */; }; @@ -385,10 +387,12 @@ 0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = ""; }; 0AA33B33239813C50067DD0F /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = ""; }; 0AA33B392398524F0067DD0F /* Toggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toggle.swift; sourceTree = ""; }; - 0ABD136A237B193A0081388D /* EntryFieldContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = ""; }; 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = ""; }; 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = ""; }; + 0ACDF26A23DA0AC2002044B2 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = ""; }; 0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = ""; }; + 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = ""; }; + 31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = ""; }; 9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = ""; }; 943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = ""; }; 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = ""; }; @@ -698,7 +702,7 @@ isa = PBXGroup; children = ( D29E28DE23D740FC00ACEA85 /* Container */, - 0ABD136A237B193A0081388D /* EntryFieldContainer.swift */, + 0ACDF26A23DA0AC2002044B2 /* EntryFieldContainer.swift */, 014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */, D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */, ); @@ -1161,7 +1165,9 @@ D268C711238D6699007F2C1C /* DropDown.swift */, DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */, 94C2D9822386F3E30006CF46 /* Label */, + 31BE15CA23D8924C00452370 /* CheckboxModel.swift */, 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */, + 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */, 0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */, 01004F2F22721C3800991ECC /* RadioButton.swift */, D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */, @@ -1492,6 +1498,7 @@ 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 */, D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */, @@ -1579,6 +1586,7 @@ DBEFFA04225A829700230692 /* Label.swift in Sources */, D2D6CD4022E78C1A00D701B8 /* Scroller.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 */, @@ -1616,6 +1624,7 @@ 017BEB7F23676E870024EF95 /* MoleculeObjectMapping.swift in Sources */, D274CA332236A78900B01B62 /* FooterView.swift in Sources */, D29DF2BF21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.m in Sources */, + 0ACDF26B23DA0AC2002044B2 /* EntryFieldContainer.swift in Sources */, 014AA72423C501E2006F3E93 /* MoleculeContainerModel.swift in Sources */, D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */, 011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */, @@ -1698,7 +1707,6 @@ D2B18B922361E65A00A9AEDC /* CoreUIObject.swift in Sources */, D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */, 014AA72E23C5059B006F3E93 /* StackCenteredPageTemplateModel.swift in Sources */, - 0ABD136B237B193A0081388D /* EntryFieldContainer.swift in Sources */, D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */, D260105923D0A92900764D80 /* ContainerProtocol.swift in Sources */, C695A69423C9909000BFB94E /* DoughnutChartModel.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Views/Checkbox.swift b/MVMCoreUI/Atoms/Views/Checkbox.swift index 50571e30..27bed31e 100644 --- a/MVMCoreUI/Atoms/Views/Checkbox.swift +++ b/MVMCoreUI/Atoms/Views/Checkbox.swift @@ -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, 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 diff --git a/MVMCoreUI/Atoms/Views/CheckboxLabelModel.swift b/MVMCoreUI/Atoms/Views/CheckboxLabelModel.swift new file mode 100644 index 00000000..5a9d09f0 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/CheckboxLabelModel.swift @@ -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 +} diff --git a/MVMCoreUI/Atoms/Views/CheckboxModel.swift b/MVMCoreUI/Atoms/Views/CheckboxModel.swift new file mode 100644 index 00000000..aa5dedb4 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/CheckboxModel.swift @@ -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) + } +} diff --git a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift index 229efe2a..bc23db73 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift @@ -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 diff --git a/MVMCoreUI/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atoms/Views/Label/Label.swift index b2953227..208676df 100644 --- a/MVMCoreUI/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label/Label.swift @@ -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) } } diff --git a/MVMCoreUI/Containers/views/EntryFieldContainer.swift b/MVMCoreUI/Containers/views/EntryFieldContainer.swift deleted file mode 100644 index 96a51a8f..00000000 --- a/MVMCoreUI/Containers/views/EntryFieldContainer.swift +++ /dev/null @@ -1,285 +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. - weak 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 -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 } - } -} diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index f7cf5c57..c53fccd2 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -44,6 +44,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)