Merge branch 'develop' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui into feature/carousel_form_changes

This commit is contained in:
Khan, Arshad 2021-02-17 18:26:42 +05:30
commit bc0ed88db9
23 changed files with 582 additions and 129 deletions

View File

@ -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 = "<group>"; };
01EB368D23609801006832FA /* HeadlineBodyModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeadlineBodyModel.swift; sourceTree = "<group>"; };
01F2A03123A4498200D954D8 /* CaretLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaretLinkModel.swift; sourceTree = "<group>"; };
0A0FEC7325D42A5E00AF2548 /* BaseItemPickerEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseItemPickerEntryField.swift; sourceTree = "<group>"; };
0A0FEC7725D42A8500AF2548 /* BaseItemPickerEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseItemPickerEntryFieldModel.swift; sourceTree = "<group>"; };
0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionDetailWithImage.swift; sourceTree = "<group>"; };
0A209CD223A7E2810068F8B0 /* UIStackViewAlignment+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackViewAlignment+Extension.swift"; sourceTree = "<group>"; };
0A21DB7E235DECC500C160A2 /* EntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryField.swift; sourceTree = "<group>"; };
@ -645,7 +651,7 @@
0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryFieldModel.swift; sourceTree = "<group>"; };
0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MdnEntryFieldModel.swift; sourceTree = "<group>"; };
0A7EF86023D8AC2500B2AAD1 /* DigitEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitEntryFieldModel.swift; sourceTree = "<group>"; };
0A7EF86223D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseDropdownEntryFieldModel.swift; sourceTree = "<group>"; };
0A7EF86223D8AFA000B2AAD1 /* BaseDropdownFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseDropdownFieldModel.swift; sourceTree = "<group>"; };
0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryFieldModel.swift; sourceTree = "<group>"; };
0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryFieldModel.swift; sourceTree = "<group>"; };
0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = "<group>"; };
@ -666,6 +672,8 @@
0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = "<group>"; };
0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = "<group>"; };
0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
0AE277E825D2ED4B0048A38D /* MultiItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiItemDropdownEntryField.swift; sourceTree = "<group>"; };
0AE277EB25D2EE310048A38D /* MultiItemDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiItemDropdownEntryFieldModel.swift; sourceTree = "<group>"; };
0AE98BAE23FEF956004C5109 /* ExternalLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalLink.swift; sourceTree = "<group>"; };
0AE98BB223FF0934004C5109 /* ExternalLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalLinkModel.swift; sourceTree = "<group>"; };
0AE98BB423FF18D2004C5109 /* Arrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arrow.swift; sourceTree = "<group>"; };
@ -1183,6 +1191,39 @@
path = FormUIHelpers;
sourceTree = "<group>";
};
0A0FEC7125D4246000AF2548 /* Dropdown Fields */ = {
isa = PBXGroup;
children = (
0A7EF86223D8AFA000B2AAD1 /* BaseDropdownFieldModel.swift */,
0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */,
0A0FEC8D25D4487F00AF2548 /* Date Dropdown */,
0A0FEC8A25D4486F00AF2548 /* Item Dropdown */,
);
path = "Dropdown Fields";
sourceTree = "<group>";
};
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 = "<group>";
};
0A0FEC8D25D4487F00AF2548 /* Date Dropdown */ = {
isa = PBXGroup;
children = (
0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */,
0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */,
);
path = "Date Dropdown";
sourceTree = "<group>";
};
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 = "<group>";
@ -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 */,

View File

@ -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

View File

@ -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
}
}

View File

@ -15,7 +15,7 @@
public override class var identifier: String { "digitTextField" }
public var digits: Int = 4
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------

View File

@ -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 {

View File

@ -27,7 +27,7 @@
}
//--------------------------------------------------
// MARK: - Initializers
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {

View File

@ -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))
}

View File

@ -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") ?? "")"
}
}

View File

@ -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 { "" }
}

View File

@ -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") ?? "")"
}
}

View File

@ -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
}
}

View File

@ -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..<componentCount {
let pickerIndex = pickerView.selectedRow(inComponent: component)
dropdownModel?.selectedIndexes[component] = pickerIndex
}
}
//--------------------------------------------------
// MARK: - TextField Observation
//--------------------------------------------------
/// Observing action of the textfield for initial interaction with the picker.
@objc override func startEditing() {
super.startEditing()
setInitialValueFromPicker()
}
/// Observing action for when the user has ended inputting with the picker.
@objc override func endInputing() {
super.endInputing()
guard !pickerComponents.isEmpty,
let rowText = dropdownModel?.selectedRowText
else { return }
// update observing function with most recent selection.
observeDropdownSelection?(rowText)
}
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
//--------------------------------------------------
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? MultiItemDropdownEntryFieldModel else { return }
// Select initial rows if selectedIndexes retains value.
for (component, row) in model.selectedIndexes {
self.pickerView.selectRow(row, inComponent: component, animated: false)
self.pickerView(pickerView, didSelectRow: row, inComponent: component)
}
}
//--------------------------------------------------
// MARK: - Picker Delegate
//--------------------------------------------------
@objc public override func numberOfComponents(in pickerView: UIPickerView) -> 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
}
}

View File

@ -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..<components.count {
let pickerIndex = selectedIndexes[i] ?? 0
text += components[i][pickerIndex] + delimiter(for: i)
}
return text
}
public var selectedIndexesArray: [Int] {
var indexArray: [Int] = []
for i in 0..<selectedIndexes.count {
guard let selectIndex = selectedIndexes[i] else { return [] }
indexArray.append(selectIndex)
}
return indexArray
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case components
case selectedIndexes
case delimiters
}
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
try super.init(from: decoder)
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
components = try typeContainer.decode([[String]].self, forKey: .components)
delimiters = try typeContainer.decodeIfPresent([String].self, forKey: .delimiters)
if let indexes = try typeContainer.decodeIfPresent([Int].self, forKey: .selectedIndexes) {
for (component, index) in indexes.enumerated() {
self.selectedIndexes[component] = index
}
baseValue = selectedRowText
}
}
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(components, forKey: .components)
try container.encode(selectedIndexesArray, forKey: .selectedIndexes)
try container.encodeIfPresent(delimiters, forKey: .delimiters)
}
}

View File

@ -36,7 +36,7 @@ import UIKit
label.setContentCompressionResistancePriority(.required, for: .vertical)
return label
}()
//--------------------------------------------------
// MARK: - Delegate
//--------------------------------------------------
@ -58,7 +58,7 @@ import UIKit
/// Toggles enabled (original) or disabled UI.
public var isEnabled: Bool {
get { return entryFieldContainer.isEnabled }
get { entryFieldContainer.isEnabled }
set (enabled) {
self.titleLabel.textColor = enabled ? .mvmBlack : .mvmCoolGray3
self.feedbackLabel.textColor = enabled ? .mvmBlack : .mvmCoolGray3
@ -69,7 +69,7 @@ import UIKit
/// Toggles error or original UI.
public var showError: Bool {
get { return entryFieldContainer.showError }
get { entryFieldContainer.showError }
set (error) {
self.feedback = error ? errorMessage : entryFieldModel?.feedback
self.feedbackLabel.textColor = error ? entryFieldModel?.errorTextColor?.uiColor ?? .mvmBlack : .mvmBlack
@ -84,7 +84,7 @@ import UIKit
/// Toggles original or locked UI.
public var isLocked: Bool {
get { return entryFieldContainer.isLocked }
get { entryFieldContainer.isLocked }
set (locked) {
self.entryFieldContainer.isLocked = locked
self.entryFieldModel?.locked = locked
@ -93,7 +93,7 @@ import UIKit
/// Toggles selected or original (unselected) UI.
public var isSelected: Bool {
get { return entryFieldContainer.isSelected }
get { entryFieldContainer.isSelected }
set (selected) {
self.entryFieldContainer.isSelected = selected
self.entryFieldModel?.selected = selected
@ -102,7 +102,7 @@ import UIKit
/// Sets the text of titleLabel
public var title: String? {
get { return titleLabel.text }
get { titleLabel.text }
set (newText) {
titleLabel.text = newText
setAccessibilityString(newText)
@ -111,13 +111,13 @@ import UIKit
/// Override this to conveniently get/set the textfield(s).
public var text: String? {
get { return nil }
get { nil }
set { fatalError("You MUST override EntryField's 'text' variable in your subclass.") }
}
/// Sets feedback text in the textField.
public var feedback: String? {
get { return feedbackLabel.text }
get { feedbackLabel.text }
set (newFeedback) {
feedbackLabel.text = newFeedback
feedbackLabel.accessibilityElementsHidden = feedbackLabel.text?.isEmpty ?? true
@ -126,7 +126,7 @@ import UIKit
}
public var entryFieldModel: EntryFieldModel? {
return model as? EntryFieldModel
model as? EntryFieldModel
}
//--------------------------------------------------
@ -223,7 +223,7 @@ import UIKit
entryFieldContainer.refreshUI()
}
/// Intended to add the interactive content (i.e. textField) to the entryFieldContainer.
/// Intended to add the interactive content (i.e. textField) to the entryFieldContainer.
@objc open func setupFieldContainerContent(_ container: UIView) {
// To Be Overriden
}

View File

@ -46,7 +46,7 @@ import Foundation
/// Temporary binding mechanism for the view to update on enable changes.
public var updateUI: ActionBlock?
// TODO: Remove once updateUI is fixed with isSelected
public var updateUIDynamicError: ActionBlock?
@ -140,9 +140,9 @@ import Foundation
try container.encodeIfPresent(selected, forKey: .selected)
try container.encodeIfPresent(errorTextColor, forKey: .errorTextColor)
try container.encodeIfPresent(errorMessage, forKey: .errorMessage)
try container.encode(enabled, forKey: .enabled)
try container.encode(hideBorders, forKey: .hideBorders)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(groupName, forKey: .groupName)
try container.encode(enabled, forKey: .enabled)
try container.encode(hideBorders, forKey: .hideBorders)
}
}

View File

@ -31,7 +31,7 @@ import MVMCore
/// 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
@ -44,7 +44,7 @@ import MVMCore
/// Formats the MDN when setting and removes format of MDN when reading.
public var mdn: String? {
get { return MVMCoreUIUtility.removeMdnFormat(text) }
get { MVMCoreUIUtility.removeMdnFormat(text) }
set { text = MVMCoreUIUtility.formatMdn(newValue) }
}
@ -160,9 +160,9 @@ import MVMCore
// Sometimes user add extra 1 in front of mdn in their address book
if isNationalMDN,
let unformedMDN = unformattedMDN,
unformedMDN.count == 11,
unformedMDN[(unformedMDN.index(unformedMDN.startIndex, offsetBy: 0))] == "1" {
let unformedMDN = unformattedMDN,
unformedMDN.count == 11,
unformedMDN[(unformedMDN.index(unformedMDN.startIndex, offsetBy: 0))] == "1" {
let startIndex = unformedMDN.index(unformedMDN.startIndex, offsetBy: 1)
unformattedMDN = String(unformedMDN[startIndex...])

View File

@ -61,7 +61,7 @@ import UIKit
//--------------------------------------------------
public override var isEnabled: Bool {
get { return super.isEnabled }
get { super.isEnabled }
set (enabled) {
super.isEnabled = enabled
@ -75,7 +75,7 @@ import UIKit
}
public override var showError: Bool {
get { return super.showError }
get { super.showError }
set (error) {
if error {
@ -96,8 +96,24 @@ import UIKit
open override var text: String? {
get { textField.text }
set {
textField.text = newValue
textEntryFieldModel?.text = newValue
guard let regex = textEntryFieldModel?.displayFormat,
let mask = textEntryFieldModel?.displayMask,
let newText = newValue
else {
textField.text = newValue
return
}
let range = NSRange(newText.startIndex..., in: newText)
if let regex = try? NSRegularExpression(pattern: regex) {
let maskedText = regex.stringByReplacingMatches(in: newText,
range: range,
withTemplate: mask)
textField.text = maskedText
}
}
}
@ -220,9 +236,7 @@ import UIKit
@discardableResult
@objc override open func resignFirstResponder() -> 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() }
}
}

View File

@ -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)
}
}

View File

@ -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

View File

@ -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
//--------------------------------------------------

View File

@ -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)

View File

@ -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 }