diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 5c490b5a..9ba02cb8 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -62,6 +62,8 @@ 01EB369323609801006832FA /* HeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368C23609801006832FA /* HeaderModel.swift */; }; 01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368D23609801006832FA /* HeadlineBodyModel.swift */; }; 01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A03123A4498200D954D8 /* CaretLinkModel.swift */; }; + 0A0FEC7425D42A5E00AF2548 /* BaseItemPickerEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A0FEC7325D42A5E00AF2548 /* BaseItemPickerEntryField.swift */; }; + 0A0FEC7825D42A8500AF2548 /* BaseItemPickerEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A0FEC7725D42A8500AF2548 /* BaseItemPickerEntryFieldModel.swift */; }; 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */; }; 0A1B4A96233BB18F005B3FB4 /* CheckboxLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */; }; 0A21DB7F235DECC500C160A2 /* EntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A21DB7E235DECC500C160A2 /* EntryField.swift */; }; @@ -94,7 +96,7 @@ 0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */; }; 0A7EF85F23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */; }; 0A7EF86123D8AC2500B2AAD1 /* DigitEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86023D8AC2500B2AAD1 /* DigitEntryFieldModel.swift */; }; - 0A7EF86323D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86223D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift */; }; + 0A7EF86323D8AFA000B2AAD1 /* BaseDropdownFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86223D8AFA000B2AAD1 /* BaseDropdownFieldModel.swift */; }; 0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */; }; 0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */; }; 0A849EFE246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A849EFD246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift */; }; @@ -114,6 +116,8 @@ 0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; }; 0AD93A9F24C0AA5100E56A97 /* ImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7918F423F5E7EA00772FF4 /* ImageView.swift */; }; 0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; }; + 0AE277E925D2ED4B0048A38D /* MultiItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE277E825D2ED4B0048A38D /* MultiItemDropdownEntryField.swift */; }; + 0AE277EC25D2EE310048A38D /* MultiItemDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE277EB25D2EE310048A38D /* MultiItemDropdownEntryFieldModel.swift */; }; 0AE98BAF23FEF956004C5109 /* ExternalLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BAE23FEF956004C5109 /* ExternalLink.swift */; }; 0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB223FF0934004C5109 /* ExternalLinkModel.swift */; }; 0AE98BB523FF18D2004C5109 /* Arrow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB423FF18D2004C5109 /* Arrow.swift */; }; @@ -612,6 +616,8 @@ 01EB368C23609801006832FA /* HeaderModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderModel.swift; sourceTree = ""; }; 01EB368D23609801006832FA /* HeadlineBodyModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeadlineBodyModel.swift; sourceTree = ""; }; 01F2A03123A4498200D954D8 /* CaretLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaretLinkModel.swift; sourceTree = ""; }; + 0A0FEC7325D42A5E00AF2548 /* BaseItemPickerEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseItemPickerEntryField.swift; sourceTree = ""; }; + 0A0FEC7725D42A8500AF2548 /* BaseItemPickerEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseItemPickerEntryFieldModel.swift; sourceTree = ""; }; 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionDetailWithImage.swift; sourceTree = ""; }; 0A209CD223A7E2810068F8B0 /* UIStackViewAlignment+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackViewAlignment+Extension.swift"; sourceTree = ""; }; 0A21DB7E235DECC500C160A2 /* EntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryField.swift; sourceTree = ""; }; @@ -645,7 +651,7 @@ 0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryFieldModel.swift; sourceTree = ""; }; 0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MdnEntryFieldModel.swift; sourceTree = ""; }; 0A7EF86023D8AC2500B2AAD1 /* DigitEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitEntryFieldModel.swift; sourceTree = ""; }; - 0A7EF86223D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseDropdownEntryFieldModel.swift; sourceTree = ""; }; + 0A7EF86223D8AFA000B2AAD1 /* BaseDropdownFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseDropdownFieldModel.swift; sourceTree = ""; }; 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryFieldModel.swift; sourceTree = ""; }; 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryFieldModel.swift; sourceTree = ""; }; 0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = ""; }; @@ -666,6 +672,8 @@ 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = ""; }; 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = ""; }; 0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = ""; }; + 0AE277E825D2ED4B0048A38D /* MultiItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiItemDropdownEntryField.swift; sourceTree = ""; }; + 0AE277EB25D2EE310048A38D /* MultiItemDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiItemDropdownEntryFieldModel.swift; sourceTree = ""; }; 0AE98BAE23FEF956004C5109 /* ExternalLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalLink.swift; sourceTree = ""; }; 0AE98BB223FF0934004C5109 /* ExternalLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalLinkModel.swift; sourceTree = ""; }; 0AE98BB423FF18D2004C5109 /* Arrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arrow.swift; sourceTree = ""; }; @@ -1183,6 +1191,39 @@ path = FormUIHelpers; sourceTree = ""; }; + 0A0FEC7125D4246000AF2548 /* Dropdown Fields */ = { + isa = PBXGroup; + children = ( + 0A7EF86223D8AFA000B2AAD1 /* BaseDropdownFieldModel.swift */, + 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */, + 0A0FEC8D25D4487F00AF2548 /* Date Dropdown */, + 0A0FEC8A25D4486F00AF2548 /* Item Dropdown */, + ); + path = "Dropdown Fields"; + sourceTree = ""; + }; + 0A0FEC8A25D4486F00AF2548 /* Item Dropdown */ = { + isa = PBXGroup; + children = ( + 0A0FEC7725D42A8500AF2548 /* BaseItemPickerEntryFieldModel.swift */, + 0A0FEC7325D42A5E00AF2548 /* BaseItemPickerEntryField.swift */, + 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */, + 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */, + 0AE277EB25D2EE310048A38D /* MultiItemDropdownEntryFieldModel.swift */, + 0AE277E825D2ED4B0048A38D /* MultiItemDropdownEntryField.swift */, + ); + path = "Item Dropdown"; + sourceTree = ""; + }; + 0A0FEC8D25D4487F00AF2548 /* Date Dropdown */ = { + isa = PBXGroup; + children = ( + 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */, + 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */, + ); + path = "Date Dropdown"; + sourceTree = ""; + }; 0A5D59C323AD488600EFD9E9 /* Protocols */ = { isa = PBXGroup; children = ( @@ -2060,14 +2101,9 @@ 0A8321AE2355FE9500CB7F00 /* DigitBox.swift */, 0A7EF86023D8AC2500B2AAD1 /* DigitEntryFieldModel.swift */, 0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */, - 0A7EF86223D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift */, - 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */, - 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */, - 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */, - 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */, - 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */, 0A25209724645B76000FA9F6 /* TextViewEntryFieldModel.swift */, 0A25209524645AFD000FA9F6 /* TextViewEntryField.swift */, + 0A0FEC7125D4246000AF2548 /* Dropdown Fields */, ); path = TextFields; sourceTree = ""; @@ -2473,6 +2509,7 @@ D264FAAA2440F97600D98315 /* CollectionView.swift in Sources */, AAC23FAD24D92A0D009208DF /* ListThreeColumnSpeedTestModel.swift in Sources */, BBC0C4FF24811DCA0087C44F /* TagModel.swift in Sources */, + 0AE277EC25D2EE310048A38D /* MultiItemDropdownEntryFieldModel.swift in Sources */, 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */, 3265B30424BCA749000D154B /* HeadersH1NoButtonsBodyText.swift in Sources */, AAA7CD69250641F90045B959 /* HeartModel.swift in Sources */, @@ -2487,6 +2524,7 @@ D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */, 94382086243238D100B43AF3 /* WebViewModel.swift in Sources */, D28764F9245A327200CB882D /* TwoLinkView.swift in Sources */, + 0AE277E925D2ED4B0048A38D /* MultiItemDropdownEntryField.swift in Sources */, D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */, 0A6682B5243769C700AD3CA1 /* TextView.swift in Sources */, D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */, @@ -2587,6 +2625,7 @@ D2CAC7CB251104E100C75681 /* NotificationXButtonModel.swift in Sources */, 014AA73123C5059B006F3E93 /* ListPageTemplateModel.swift in Sources */, AAC23FAF24D92A1E009208DF /* ListThreeColumnSpeedTest.swift in Sources */, + 0A0FEC7425D42A5E00AF2548 /* BaseItemPickerEntryField.swift in Sources */, D29DF2A221E7AF4E003B2FB9 /* MVMCoreUIUtility.m in Sources */, D29DF12B21E6851E003B2FB9 /* MVMCoreUITopAlertExpandableView.m in Sources */, D2ED27ED254B0CE700A1C293 /* ActionPopupModel.swift in Sources */, @@ -2702,6 +2741,7 @@ BB55B51D244482C1002001AD /* ListRightVariablePriceChangeBodyText.swift in Sources */, 017BEB382360C6AC0024EF95 /* RadioButtonLabel.swift in Sources */, 323AC96C24C837FF00F8E4C4 /* ListThreeColumnBillChanges.swift in Sources */, + 0A0FEC7825D42A8500AF2548 /* BaseItemPickerEntryFieldModel.swift in Sources */, D28A837923C7D5BC00DFE4FC /* PageModelProtocol.swift in Sources */, D2351C7C24A4D4C3007DF0BC /* ListRightVariableToggleAllTextAndLinks.swift in Sources */, 017BEB7B236763000024EF95 /* LineModel.swift in Sources */, @@ -2889,7 +2929,7 @@ D2D2FCF0252B72AF0033EAAA /* MoleculeSectionFooterModel.swift in Sources */, BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */, D2FA83D42514F80C00564112 /* CollapsableNotification.swift in Sources */, - 0A7EF86323D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift in Sources */, + 0A7EF86323D8AFA000B2AAD1 /* BaseDropdownFieldModel.swift in Sources */, 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */, D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */, D2B18B922361E65A00A9AEDC /* CoreUIObject.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitBox.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitBox.swift index 4d23558f..912b0891 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitBox.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitBox.swift @@ -80,7 +80,7 @@ import UIKit open override func setupView() { super.setupView() - + addSubview(digitField) digitField.delegate = self digitField.didDeleteDelegate = self @@ -140,7 +140,7 @@ import UIKit super.updateView(size) if !MVMCoreGetterUtility.fequal(a: Float(size), b: Float(previousSize)) { - + var width: CGFloat = 0 var height: CGFloat = 0 var pointSize: CGFloat = 13 diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitEntryField.swift index f3cc628e..c70d458e 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitEntryField.swift @@ -75,7 +75,7 @@ import UIKit private var selectedDigitBox: DigitBox? public var digitEntryModel: DigitEntryFieldModel? { - return model as? DigitEntryFieldModel + model as? DigitEntryFieldModel } //-------------------------------------------------- @@ -83,7 +83,7 @@ import UIKit //-------------------------------------------------- public override var isEnabled: Bool { - get { return super.isEnabled } + get { super.isEnabled } set (enabled) { digitBoxes.forEach { $0.isEnabled = enabled } super.isEnabled = enabled @@ -91,7 +91,7 @@ import UIKit } public override var showError: Bool { - get { return super.showError } + get { super.showError } set (error) { digitBoxes.forEach { $0.showError = error } super.showError = error @@ -99,7 +99,7 @@ import UIKit } public override var isLocked: Bool { - get { return super.isLocked } + get { super.isLocked } set (locked) { digitBoxes.forEach { $0.isLocked = locked } super.isLocked = locked @@ -162,7 +162,7 @@ import UIKit /// If you're using a MFViewController, you must set this to it public override weak var uiTextFieldDelegate: UITextFieldDelegate? { - get { return textField.delegate } + get { textField.delegate } set { textField.delegate = self proprietorTextDelegate = newValue @@ -450,11 +450,11 @@ extension DigitEntryField { @objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { - return proprietorTextDelegate?.textFieldShouldBeginEditing?(textField) ?? true + proprietorTextDelegate?.textFieldShouldBeginEditing?(textField) ?? true } @objc public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { - return proprietorTextDelegate?.textFieldShouldEndEditing?(textField) ?? true + proprietorTextDelegate?.textFieldShouldEndEditing?(textField) ?? true } } diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitEntryFieldModel.swift index 8003c1b0..c381637a 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitEntryFieldModel.swift @@ -15,7 +15,7 @@ public override class var identifier: String { "digitTextField" } public var digits: Int = 4 - + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/BaseDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/BaseDropdownEntryField.swift similarity index 92% rename from MVMCoreUI/Atomic/Atoms/FormFields/TextFields/BaseDropdownEntryField.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/BaseDropdownEntryField.swift index b89a56e3..5a7f1702 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/BaseDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/BaseDropdownEntryField.swift @@ -1,5 +1,5 @@ // -// BaseDropdownEntryField.swift +// BaseDropdownField.swift // MVMCoreUI // // Created by Kevin Christiano on 10/23/19. @@ -28,8 +28,9 @@ import UIKit }() public var baseDropdownEntryFieldModel: BaseDropdownEntryFieldModel? { - return model as? BaseDropdownEntryFieldModel + model as? BaseDropdownEntryFieldModel } + var additionalData: [AnyHashable: Any]? //-------------------------------------------------- @@ -54,7 +55,7 @@ import UIKit @objc required public init?(coder: NSCoder) { super.init(coder: coder) - fatalError("DropdownEntryField does not support xib.") + fatalError("\(String(describing: Self.self)) does not support xib.") } required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { @@ -86,10 +87,10 @@ import UIKit dropDownCaretView.setOptional(with: model.caretView, delegateObject, additionalData) } - public override func dismissFieldInput(_ sender: Any?) { - performDropdownAction() - super.dismissFieldInput(sender) - } + @objc public override func dismissFieldInput(_ sender: Any?) { + performDropdownAction() + super.dismissFieldInput(sender) + } func performDropdownAction() { if let baseDropdownEntryFieldModel = baseDropdownEntryFieldModel, let actionModel = baseDropdownEntryFieldModel.action { diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/BaseDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/BaseDropdownFieldModel.swift similarity index 98% rename from MVMCoreUI/Atomic/Atoms/FormFields/TextFields/BaseDropdownEntryFieldModel.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/BaseDropdownFieldModel.swift index f256544c..39701016 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/BaseDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/BaseDropdownFieldModel.swift @@ -27,7 +27,7 @@ } //-------------------------------------------------- - // MARK: - Initializers + // MARK: - Codec //-------------------------------------------------- required public init(from decoder: Decoder) throws { diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DateDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Date Dropdown/DateDropdownEntryField.swift similarity index 99% rename from MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DateDropdownEntryField.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Date Dropdown/DateDropdownEntryField.swift index c1ea8080..234809d3 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DateDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Date Dropdown/DateDropdownEntryField.swift @@ -69,6 +69,7 @@ import UIKit datePicker = UIDatePicker.addDatePicker(to: textField) datePicker?.addTarget(self, action: #selector(pickerValueChanged), for: .valueChanged) datePicker?.timeZone = NSTimeZone.system + textField.inputView = datePicker UIToolbar.addDismissToolbar(to: textField, delegate: self, action: #selector(dismissFieldInput)) } diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DateDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Date Dropdown/DateDropdownEntryFieldModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DateDropdownEntryFieldModel.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Date Dropdown/DateDropdownEntryFieldModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryField.swift new file mode 100644 index 00000000..00b5a072 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryField.swift @@ -0,0 +1,85 @@ +// +// BaseItemPickerEntryField.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 2/10/21. +// Copyright © 2021 Verizon Wireless. All rights reserved. +// + +import UIKit + +public typealias TextFieldAndPickerDelegate = (UITextFieldDelegate & UIPickerViewDelegate & UIPickerViewDataSource) + + +open class BaseItemPickerEntryField: BaseDropdownEntryField, UIPickerViewDelegate, UIPickerViewDataSource { + //-------------------------------------------------- + // MARK: - Outlets + //-------------------------------------------------- + + open lazy var pickerView = UIPickerView.addPicker(to: textField, delegate: self, dismissAction: #selector(dismissFieldInput)) + + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + /// Closure passed here will run as picker changes items. + public var observeDropdownChange: ((String, String) -> ())? + + /// Closure passed here will run upon dismissing the selection picker. + public var observeDropdownSelection: ((String) -> ())? + + /// When selecting for first responder, allow initial selected value to appear in empty text field. + public var setInitialValueInTextField = true + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + + @objc open override func setupFieldContainerContent(_ container: UIView) { + super.setupFieldContainerContent(container) + + textField.hideBlinkingCaret = true + textField.autocorrectionType = .no + uiTextFieldDelegate = self + } + + @objc public func setPickerDelegates(delegate: UIPickerViewDelegate & UIPickerViewDataSource) { + + pickerView.delegate = delegate + pickerView.dataSource = delegate + } + + //-------------------------------------------------- + // MARK: - Molecular + //-------------------------------------------------- + + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) + + setPickerDelegates(delegate: self) + } + + //-------------------------------------------------- + // MARK: - Picker Delegate to Override + //-------------------------------------------------- + + public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 0 } + + public func numberOfComponents(in pickerView: UIPickerView) -> Int { 0 } +} + + +// MARK: - Accessibility +extension BaseItemPickerEntryField { + + @objc open override func setAccessibilityString(_ accessibilityString: String?) { + + var accessibilityString = accessibilityString ?? "" + + if let textPickerItem = MVMCoreUIUtility.hardcodedString(withKey: "textfield_picker_item") { + accessibilityString += textPickerItem + } + + textField.accessibilityLabel = "\(accessibilityString) \(textField.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state") ?? "")" + } +} diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryFieldModel.swift new file mode 100644 index 00000000..a2b3d696 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryFieldModel.swift @@ -0,0 +1,18 @@ +// +// BaseItemPickerEntryFieldModel.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 2/10/21. +// Copyright © 2021 Verizon Wireless. All rights reserved. +// + +import UIKit + + +open class BaseItemPickerEntryFieldModel: BaseDropdownEntryFieldModel { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public override class var identifier: String { "" } +} diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/ItemDropdownEntryField.swift similarity index 54% rename from MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryField.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/ItemDropdownEntryField.swift index 9002d701..b3aeb172 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/ItemDropdownEntryField.swift @@ -8,28 +8,16 @@ import UIKit -public typealias TextFieldAndPickerDelegate = (UITextFieldDelegate & UIPickerViewDelegate & UIPickerViewDataSource) - -open class ItemDropdownEntryField: BaseDropdownEntryField { +open class ItemDropdownEntryField: BaseItemPickerEntryField { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- open var pickerData: [String] = [] - open var pickerView: UIPickerView? - - /// When selecting for first responder, allow initial selected value to appear in empty text field. - public var setInitialValueInTextField = true - - /// Closure passed here will run as picker changes items. - public var observeDropdownChange: ((String, String)->())? - - /// Closure passed here will run upon dismissing the selection picker. - public var observeDropdownSelection: ((String)->())? public var itemDropdownEntryFieldModel: ItemDropdownEntryFieldModel? { - return model as? ItemDropdownEntryFieldModel + model as? ItemDropdownEntryFieldModel } //-------------------------------------------------- @@ -61,26 +49,13 @@ open class ItemDropdownEntryField: BaseDropdownEntryField { // MARK: - Methods //-------------------------------------------------- - @objc open override func setupFieldContainerContent(_ container: UIView) { - super.setupFieldContainerContent(container) - - pickerView = UIPickerView.addPicker(to: textField, delegate: self, dismissAction: #selector(dismissFieldInput)) - textField.hideBlinkingCaret = true - textField.autocorrectionType = .no - uiTextFieldDelegate = self - } - - @objc public func setPickerDelegates(delegate: UIPickerViewDelegate & UIPickerViewDataSource) { - - pickerView?.delegate = delegate - pickerView?.dataSource = delegate - } - + /// Sets the textField with the first value of the available picker data. @objc private func setInitialValueFromPicker() { guard !pickerData.isEmpty else { return } - if setInitialValueInTextField, let pickerIndex = pickerView?.selectedRow(inComponent: 0) { + if setInitialValueInTextField { + let pickerIndex = pickerView.selectedRow(inComponent: 0) observeDropdownChange?(text ?? "", pickerData[pickerIndex]) text = pickerData[pickerIndex] itemDropdownEntryFieldModel?.selectedIndex = pickerIndex @@ -98,9 +73,7 @@ open class ItemDropdownEntryField: BaseDropdownEntryField { guard !pickerData.isEmpty else { return } - if let pickerIndex = pickerView?.selectedRow(inComponent: 0) { - observeDropdownSelection?(pickerData[pickerIndex]) - } + observeDropdownSelection?(pickerData[pickerView.selectedRow(inComponent: 0)]) } public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { @@ -109,20 +82,20 @@ open class ItemDropdownEntryField: BaseDropdownEntryField { guard let model = model as? ItemDropdownEntryFieldModel else { return } pickerData = model.options - setPickerDelegates(delegate: self) - if let pickerView = pickerView, let index = model.selectedIndex { + if let index = model.selectedIndex { + self.pickerView.selectRow(index, inComponent: 0, animated: false) self.pickerView(pickerView, didSelectRow: index, inComponent: 0) } } -} -// MARK:- Base Picker Delegate -extension ItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource { + //-------------------------------------------------- + // MARK: - Picker Delegate + //-------------------------------------------------- - @objc public func numberOfComponents(in pickerView: UIPickerView) -> Int { 1 } + @objc public override func numberOfComponents(in pickerView: UIPickerView) -> Int { 1 } - @objc public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + @objc public override func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { pickerData.count } @@ -140,18 +113,3 @@ extension ItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource { itemDropdownEntryFieldModel?.selectedIndex = row } } - -// MARK: - Accessibility -extension ItemDropdownEntryField { - - @objc open override func setAccessibilityString(_ accessibilityString: String?) { - - var accessibilityString = accessibilityString ?? "" - - if let textPickerItem = MVMCoreUIUtility.hardcodedString(withKey: "textfield_picker_item") { - accessibilityString += textPickerItem - } - - textField.accessibilityLabel = "\(accessibilityString) \(textField.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state") ?? "")" - } -} diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/ItemDropdownEntryFieldModel.swift similarity index 81% rename from MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryFieldModel.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/ItemDropdownEntryFieldModel.swift index 10650e20..bf7416e6 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/ItemDropdownEntryFieldModel.swift @@ -6,7 +6,7 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -@objcMembers open class ItemDropdownEntryFieldModel: BaseDropdownEntryFieldModel { +@objcMembers open class ItemDropdownEntryFieldModel: BaseItemPickerEntryFieldModel { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -15,11 +15,15 @@ public var options: [String] = [] public var selectedIndex: Int? - + + //-------------------------------------------------- + // MARK: - Validation + //-------------------------------------------------- + public override func formFieldValue() -> AnyHashable? { guard !options.isEmpty, - let index = selectedIndex - else { return nil } + let index = selectedIndex + else { return nil } return options[index] } @@ -32,7 +36,7 @@ case options case selectedIndex } - + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -45,10 +49,7 @@ if let selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) { self.selectedIndex = selectedIndex - } - - if let index = selectedIndex { - baseValue = options.indices.contains(index) ? options[index] : nil + baseValue = options.indices.contains(selectedIndex) ? options[selectedIndex] : nil } } diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/MultiItemDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/MultiItemDropdownEntryField.swift new file mode 100644 index 00000000..2c509bb3 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/MultiItemDropdownEntryField.swift @@ -0,0 +1,144 @@ +// +// MultiItemDropdownEndryField.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 2/9/21. +// Copyright © 2021 Verizon Wireless. All rights reserved. +// + +import UIKit + + +open class MultiItemDropdownEntryField: BaseItemPickerEntryField { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + /// Datasource of the picker view. + open var pickerComponents: [[String]] { + dropdownModel?.components ?? [[]] + } + + public var dropdownModel: MultiItemDropdownEntryFieldModel? { + model as? MultiItemDropdownEntryFieldModel + } + + /// The number of components available + public var componentCount: Int { + pickerComponents.count + } + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + + @objc public override init(frame: CGRect) { + super.init(frame: frame) + } + + @objc public convenience init() { + self.init(frame: .zero) + } + + @objc required public init?(coder: NSCoder) { + fatalError("MultiItemDropdownEntryField init(coder:) has not been implemented") + } + + required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.init(model: model, delegateObject, additionalData) + } + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + + /// Sets the textField with the first value of the available picker data. + @objc private func setInitialValueFromPicker() { + + guard setInitialValueInTextField, + !pickerComponents.isEmpty, + let rowText = dropdownModel?.selectedRowText + else { return } + + // Update observing function and update text UI. + observeDropdownChange?(text ?? "", rowText) + text = rowText + + // Set row index value of selected component. + for component in 0.. Int { componentCount } + + @objc public override func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + pickerComponents[component].count + } + + @objc public func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + + guard !pickerComponents.isEmpty, + !pickerComponents[component].isEmpty + else { return nil } + + return pickerComponents[component][row] + } + + @objc public func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + + guard !pickerComponents.isEmpty, + !pickerComponents[component].isEmpty + else { return } + + let oldText = text ?? "" + dropdownModel?.selectedIndexes[component] = row + let newText = dropdownModel?.selectedRowText + observeDropdownChange?(oldText, newText ?? "") + text = newText + } +} diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/MultiItemDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/MultiItemDropdownEntryFieldModel.swift new file mode 100644 index 00000000..fbdde6f3 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/MultiItemDropdownEntryFieldModel.swift @@ -0,0 +1,104 @@ +// +// MultiItemDropdownEntryFieldModel.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 2/9/21. +// Copyright © 2021 Verizon Wireless. All rights reserved. +// + +import Foundation + + +@objcMembers open class MultiItemDropdownEntryFieldModel: BaseItemPickerEntryFieldModel { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public override class var identifier: String { "multiDropdown" } + + public var components: [[String]] = [[]] + public var selectedIndexes: [Int: Int] = [:] + public var delimiters: [String]? + + //-------------------------------------------------- + // MARK: - Validation + //-------------------------------------------------- + + public override func formFieldValue() -> AnyHashable? { + + guard !components.isEmpty && !selectedIndexes.isEmpty else { return nil } + + return selectedRowText + } + + public func delimiter(for index: Int) -> String { + + guard let delimiters = delimiters else { return " " } + guard index != components.count - 1 else { return "" } + + return delimiters[index] + } + + /// A string of the picker row concatenated by whitespace or delimiters if provided. + public var selectedRowText: String { + + var text = "" + + for i in 0.. Bool { - if validateWhenDoneEditing { - validateText() - } + if validateWhenDoneEditing { validateText() } textField.resignFirstResponder() isSelected = false return true @@ -237,6 +251,11 @@ import UIKit /// Executes on UITextField.textDidBeginEditingNotification @objc override func startEditing() { super.startEditing() + + if textEntryFieldModel?.clearTextOnTap ?? false { + text = "" + } + textField.becomeFirstResponder() } @@ -255,7 +274,7 @@ import UIKit showError = false return } - + if let isValid = textEntryFieldModel?.isValid { self.isValid = isValid } @@ -315,6 +334,10 @@ import UIKit case .password, .secure: textField.isSecureTextEntry = true + case .numberSecure: + textField.isSecureTextEntry = true + textField.keyboardType = .numberPad + case .number: textField.keyboardType = .numberPad @@ -324,8 +347,12 @@ import UIKit case .phone: textField.keyboardType = .phonePad - default: - break + default: break + } + + // Override the preset keyboard set in type. + if let keyboardType = model.assignKeyboardType() { + textField.keyboardType = keyboardType } textField.accessibilityIdentifier = model.accessibilityIdentifier @@ -333,9 +360,7 @@ import UIKit observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate setupTextFieldToolbar() - if isSelected { - startEditing() - } + if isSelected { startEditing() } } } diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryFieldModel.swift index 5bdc26cc..ca7543bd 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryFieldModel.swift @@ -16,6 +16,7 @@ case password case secure case number + case numberSecure case email case text case phone @@ -31,7 +32,63 @@ public var enabledTextColor: Color = Color(uiColor: .mvmBlack) public var disabledTextColor: Color = Color(uiColor: .mvmCoolGray3) public var textAlignment: NSTextAlignment = .left + public var keyboardOverride: String? public var type: EntryType? + public var clearTextOnTap: Bool = false + public var displayFormat: String? + public var displayMask: String? + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + + /// Reads the keyboardOverride set by server and returns the keyboard type associated with it. + func assignKeyboardType() -> UIKeyboardType? { + + guard let keyboardType = keyboardOverride else { return nil } + + var typeInt = 0 + + switch keyboardType { + case "asciiCapable": + typeInt = 1 // Displays a keyboard which can enter ASCII characters + + case "numbersAndPunctuation": + typeInt = 2 // Numbers and assorted punctuation. + + case "URL": + typeInt = 3 // A type optimized for URL entry (shows . / .com prominently). + + case "numberPad": + typeInt = 4 // A number pad with locale-appropriate digits (0-9, ۰-۹, ०-९, etc.). Suitable for PIN entry. + + case "phonePad": + typeInt = 5 // A phone pad (1-9, *, 0, #, with letters under the numbers). + + case "namePhonePad": + typeInt = 6 // A type optimized for entering a person's name or phone number. + + case "emailAddress": + typeInt = 7 // A type optimized for multiple email address entry (shows space @ . prominently). + + case "decimalPad": + typeInt = 8 // A number pad with a decimal point. + + case "twitter": + typeInt = 9 // A type optimized for twitter text entry (easy access to @ #) + + case "webSearch": + typeInt = 10 // A default keyboard type with URL-oriented addition (shows space . prominently). + + case "asciiCapableNumberPad": + typeInt = 11 // A number pad (0-9) that will always be ASCII digits. + + default: + typeInt = 0 // Default type for the current input method. + } + + return UIKeyboardType(rawValue: typeInt) + } //-------------------------------------------------- // MARK: - Keys @@ -42,7 +99,11 @@ case textAlignment case enabledTextColor case disabledTextColor + case keyboardOverride case type + case clearTextOnTap + case displayFormat + case displayMask } //-------------------------------------------------- @@ -54,8 +115,15 @@ let typeContainer = try decoder.container(keyedBy: CodingKeys.self) placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder) + displayFormat = try typeContainer.decodeIfPresent(String.self, forKey: .displayFormat) + keyboardOverride = try typeContainer.decodeIfPresent(String.self, forKey: .keyboardOverride) + displayMask = try typeContainer.decodeIfPresent(String.self, forKey: .displayMask) type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type) + if let clearTextOnTap = try typeContainer.decodeIfPresent(Bool.self, forKey: .clearTextOnTap) { + self.clearTextOnTap = clearTextOnTap + } + if let enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor) { self.enabledTextColor = enabledTextColor } @@ -74,8 +142,12 @@ var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(placeholder, forKey: .placeholder) try container.encodeIfPresent(textAlignment, forKey: .textAlignment) + try container.encodeIfPresent(type, forKey: .type) + try container.encodeIfPresent(displayFormat, forKey: .displayFormat) + try container.encodeIfPresent(keyboardOverride, forKey: .keyboardOverride) + try container.encodeIfPresent(displayMask, forKey: .displayMask) try container.encode(enabledTextColor, forKey: .enabledTextColor) try container.encode(disabledTextColor, forKey: .disabledTextColor) - try container.encodeIfPresent(type, forKey: .type) + try container.encode(clearTextOnTap, forKey: .clearTextOnTap) } } diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextViewEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextViewEntryField.swift index b964ee8c..543469c1 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextViewEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextViewEntryField.swift @@ -149,17 +149,17 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele @objc open override func setupFieldContainerContent(_ container: UIView) { container.addSubview(textView) - + topConstraint = textView.topAnchor.constraint(equalTo: container.topAnchor, constant: Padding.Three) leadingConstraint = textView.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: Padding.Three) trailingConstraint = container.trailingAnchor.constraint(equalTo: textView.trailingAnchor, constant: Padding.Three) bottomConstraint = container.bottomAnchor.constraint(equalTo: textView.bottomAnchor, constant: Padding.Three) - + topConstraint?.isActive = true leadingConstraint?.isActive = true trailingConstraint?.isActive = true bottomConstraint?.isActive = true - + heightConstraint = textView.heightAnchor.constraint(equalToConstant: 0) accessibilityElements = [titleLabel, textView, feedbackLabel] } @@ -203,7 +203,7 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele /// Executes on UITextView.textDidEndEditingNotification @objc override func endInputing() { super.endInputing() - + // Don't show error till user starts typing. guard text?.count ?? 0 != 0 else { showError = false @@ -253,6 +253,10 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele case .secure, .password: textView.isSecureTextEntry = true + case .numberSecure: + textView.isSecureTextEntry = true + textView.keyboardType = .numberPad + case .number: textView.keyboardType = .numberPad diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextViewEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextViewEntryFieldModel.swift index 00a07a1c..42da3ca2 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextViewEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextViewEntryFieldModel.swift @@ -23,7 +23,7 @@ class TextViewEntryFieldModel: TextEntryFieldModel { public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro public var editable: Bool = true public var showsPlaceholder: Bool = false - + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index e4d3a59a..3dfed18d 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -79,6 +79,7 @@ import Foundation 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) + MoleculeObjectMapping.shared()?.register(viewClass: MultiItemDropdownEntryField.self, viewModelClass: MultiItemDropdownEntryFieldModel.self) // MARK:- Selectors MoleculeObjectMapping.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self) diff --git a/MVMCoreUI/FormUIHelpers/FormFieldProtocol.swift b/MVMCoreUI/FormUIHelpers/FormFieldProtocol.swift index f769e040..afdde887 100644 --- a/MVMCoreUI/FormUIHelpers/FormFieldProtocol.swift +++ b/MVMCoreUI/FormUIHelpers/FormFieldProtocol.swift @@ -7,10 +7,9 @@ // // Form fields are items can be interacted with. They have value, and may need to be validated. -import Foundation - public protocol FormFieldProtocol: FormItemProtocol { + /// How the validator identifies the field when validating rules. var fieldKey: String? { get set }