From 8b49de569d83c4947e2394c85e3184085791335e Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 9 Feb 2021 11:30:38 -0500 Subject: [PATCH] decision to separate out into a separate molecule. --- MVMCoreUI.xcodeproj/project.pbxproj | 8 + .../TextFields/ItemDropdownEntryField.swift | 95 +++----- .../ItemDropdownEntryFieldModel.swift | 66 +----- .../MultiItemDropdownEndryField.swift | 210 ++++++++++++++++++ .../MultiItemDropdownEndryFieldModel.swift | 116 ++++++++++ .../Items/DropDownFilterTableViewCell.swift | 15 +- 6 files changed, 384 insertions(+), 126 deletions(-) create mode 100644 MVMCoreUI/Atomic/Atoms/FormFields/TextFields/MultiItemDropdownEndryField.swift create mode 100644 MVMCoreUI/Atomic/Atoms/FormFields/TextFields/MultiItemDropdownEndryFieldModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 9f7816ec..6c7795a7 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -114,6 +114,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 /* MultiItemDropdownEndryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE277E825D2ED4B0048A38D /* MultiItemDropdownEndryField.swift */; }; + 0AE277EC25D2EE310048A38D /* MultiItemDropdownEndryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE277EB25D2EE310048A38D /* MultiItemDropdownEndryFieldModel.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 */; }; @@ -659,6 +661,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 /* MultiItemDropdownEndryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiItemDropdownEndryField.swift; sourceTree = ""; }; + 0AE277EB25D2EE310048A38D /* MultiItemDropdownEndryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiItemDropdownEndryFieldModel.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 = ""; }; @@ -2047,6 +2051,8 @@ 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */, 0A25209724645B76000FA9F6 /* TextViewEntryFieldModel.swift */, 0A25209524645AFD000FA9F6 /* TextViewEntryField.swift */, + 0AE277EB25D2EE310048A38D /* MultiItemDropdownEndryFieldModel.swift */, + 0AE277E825D2ED4B0048A38D /* MultiItemDropdownEndryField.swift */, ); path = TextFields; sourceTree = ""; @@ -2452,6 +2458,7 @@ D264FAAA2440F97600D98315 /* CollectionView.swift in Sources */, AAC23FAD24D92A0D009208DF /* ListThreeColumnSpeedTestModel.swift in Sources */, BBC0C4FF24811DCA0087C44F /* TagModel.swift in Sources */, + 0AE277EC25D2EE310048A38D /* MultiItemDropdownEndryFieldModel.swift in Sources */, 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */, 3265B30424BCA749000D154B /* HeadersH1NoButtonsBodyText.swift in Sources */, AAA7CD69250641F90045B959 /* HeartModel.swift in Sources */, @@ -2466,6 +2473,7 @@ D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */, 94382086243238D100B43AF3 /* WebViewModel.swift in Sources */, D28764F9245A327200CB882D /* TwoLinkView.swift in Sources */, + 0AE277E925D2ED4B0048A38D /* MultiItemDropdownEndryField.swift in Sources */, D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */, 0A6682B5243769C700AD3CA1 /* TextView.swift in Sources */, D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryField.swift index 799a8b1f..c8d5e4b5 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryField.swift @@ -12,37 +12,24 @@ public typealias TextFieldAndPickerDelegate = (UITextFieldDelegate & UIPickerVie open class ItemDropdownEntryField: BaseDropdownEntryField { - //-------------------------------------------------- - // MARK: - Outlets - //-------------------------------------------------- - - open var pickerView: UIPickerView? - //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - /// Datasource of the picker view. - open var pickerComponents: [[String]] { - dropdownModel?.options ?? [[]] - } + 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) -> ())? + public var observeDropdownChange: ((String, String)->())? /// Closure passed here will run upon dismissing the selection picker. - public var observeDropdownSelection: ((String) -> ())? + public var observeDropdownSelection: ((String)->())? - public var dropdownModel: ItemDropdownEntryFieldModel? { - model as? ItemDropdownEntryFieldModel - } - - /// The number of components available - public var componentCount: Int { - pickerComponents.count + public var itemDropdownEntryFieldModel: ItemDropdownEntryFieldModel? { + return model as? ItemDropdownEntryFieldModel } //-------------------------------------------------- @@ -57,6 +44,11 @@ open class ItemDropdownEntryField: BaseDropdownEntryField { self.init(frame: .zero) } + @objc public convenience init(pickerData: [String]) { + self.init(frame: .zero) + self.pickerData = pickerData + } + @objc required public init?(coder: NSCoder) { fatalError("ItemDropdownEntryField init(coder:) has not been implemented") } @@ -87,89 +79,66 @@ open class ItemDropdownEntryField: BaseDropdownEntryField { /// 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 } + guard !pickerData.isEmpty else { return } - observeDropdownChange?(text ?? "", rowText) - text = rowText - - for component in 0.. Int { componentCount } + @objc public func numberOfComponents(in pickerView: UIPickerView) -> Int { 1 } @objc public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { - pickerComponents[component].count + pickerData.count } @objc public func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + guard !pickerData.isEmpty else { return nil } - guard !pickerComponents.isEmpty, - !pickerComponents[component].isEmpty - else { return nil } - - return pickerComponents[component][row] + return pickerData[row] } @objc public func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + guard !pickerData.isEmpty else { return } - guard !pickerComponents.isEmpty, - !pickerComponents[component].isEmpty, - let rowText = dropdownModel?.selectedRowText - else { return } - - observeDropdownChange?(text ?? "", rowText) - text = rowText - dropdownModel?.selectedIndicies[component] = row + observeDropdownChange?(text ?? "", pickerData[row]) + text = pickerData[row] + itemDropdownEntryFieldModel?.selectedIndex = row } } diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryFieldModel.swift index a147e78a..10650e20 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryFieldModel.swift @@ -13,46 +13,15 @@ public override class var identifier: String { "dropDown" } - public var options: [[String]] = [[]] - public var selectedIndicies: [Int: Int] = [:] - - @available(*, deprecated, message: "Here for backwards compatibility for when this options was a single array.") + public var options: [String] = [] public var selectedIndex: Int? - - //-------------------------------------------------- - // MARK: - Validation - //-------------------------------------------------- - + public override func formFieldValue() -> AnyHashable? { + guard !options.isEmpty, + let index = selectedIndex + else { return nil } - guard !options.isEmpty && !selectedIndicies.isEmpty else { return nil } - - return selectedRowText - } - - /// A string of the picker row concatenated by whitespace. - public var selectedRowText: String { - - var text = "" - - for i in 0.. ())? + + /// Closure passed here will run upon dismissing the selection picker. + public var observeDropdownSelection: ((String) -> ())? + + public var dropdownModel: ItemDropdownEntryFieldModel? { + model as? ItemDropdownEntryFieldModel + } + + /// 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("ItemDropdownEntryField init(coder:) has not been implemented") + } + + required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.init(model: model, delegateObject, additionalData) + } + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + + @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 setInitialValueInTextField, + !pickerComponents.isEmpty, + let rowText = dropdownModel?.selectedRowText + else { return } + + observeDropdownChange?(text ?? "", rowText) + text = rowText + + for component in 0.. Int { componentCount } + + @objc public 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, + let rowText = dropdownModel?.selectedRowText + else { return } + + observeDropdownChange?(text ?? "", rowText) + text = rowText + dropdownModel?.selectedIndicies[component] = 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/MultiItemDropdownEndryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/MultiItemDropdownEndryFieldModel.swift new file mode 100644 index 00000000..fb9e62f0 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/MultiItemDropdownEndryFieldModel.swift @@ -0,0 +1,116 @@ +// +// MultiItemDropdownEndryFieldModel.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 2/9/21. +// Copyright © 2021 Verizon Wireless. All rights reserved. +// + +import Foundation + + +class MultiItemDropdownEndryFieldModel { + +} + + +/* + @objcMembers open class ItemDropdownEntryFieldModel: BaseDropdownEntryFieldModel { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public override class var identifier: String { "dropDown" } + + public var options: [[String]] = [[]] + public var selectedIndicies: [Int: Int] = [:] + + @available(*, deprecated, message: "Here for backwards compatibility for when this options was a single array.") + public var selectedIndex: Int? + + //-------------------------------------------------- + // MARK: - Validation + //-------------------------------------------------- + + public override func formFieldValue() -> AnyHashable? { + + guard !options.isEmpty && !selectedIndicies.isEmpty else { return nil } + + return selectedRowText + } + + /// A string of the picker row concatenated by whitespace. + public var selectedRowText: String { + + var text = "" + + for i in 0..