Merge branch 'feature/atomic-vds-inputField' into 'develop'

VDS Brand 3.0 Input Field

### Summary
VDS Brand 3.0 Input Field for IOS

### JIRA Ticket
https://onejira.verizon.com/browse/ONEAPP-7963

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1156
This commit is contained in:
Pfeil, Scott Robert 2024-07-30 18:19:59 +00:00
commit d0a6bdda3d
8 changed files with 448 additions and 122 deletions

View File

@ -582,6 +582,7 @@
EA17584C2BC9894800A5C0D9 /* ButtonIconModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA17584B2BC9894800A5C0D9 /* ButtonIconModel.swift */; };
EA17584E2BC9895A00A5C0D9 /* ButtonIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA17584D2BC9895A00A5C0D9 /* ButtonIcon.swift */; };
EA1B02DE2C41BFD200F0758B /* RuleVDSModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1B02DD2C41BFD200F0758B /* RuleVDSModel.swift */; };
EA1B02E02C470AFD00F0758B /* InputEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1B02DF2C470AFD00F0758B /* InputEntryField.swift */; };
EA41F4AC2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */; };
EA5124FD243601600051A3A4 /* BGImageHeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */; };
EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */; };
@ -1207,6 +1208,7 @@
EA17584B2BC9894800A5C0D9 /* ButtonIconModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonIconModel.swift; sourceTree = "<group>"; };
EA17584D2BC9895A00A5C0D9 /* ButtonIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonIcon.swift; sourceTree = "<group>"; };
EA1B02DD2C41BFD200F0758B /* RuleVDSModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleVDSModel.swift; sourceTree = "<group>"; };
EA1B02DF2C470AFD00F0758B /* InputEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputEntryField.swift; sourceTree = "<group>"; };
EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicRuleFormFieldEffectModel.swift; sourceTree = "<group>"; };
EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButton.swift; sourceTree = "<group>"; };
EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButtonModel.swift; sourceTree = "<group>"; };
@ -2360,6 +2362,7 @@
children = (
0A7EF85A23D8A52800B2AAD1 /* EntryFieldModel.swift */,
0A21DB7E235DECC500C160A2 /* EntryField.swift */,
EA1B02DF2C470AFD00F0758B /* InputEntryField.swift */,
0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */,
0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */,
0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */,
@ -3152,6 +3155,7 @@
323AC96A24C837F000F8E4C4 /* ListThreeColumnBillChangesModel.swift in Sources */,
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */,
EA1B02E02C470AFD00F0758B /* InputEntryField.swift in Sources */,
D28BA730247EC2EB00B75CB8 /* NavigationButtonModelProtocol.swift in Sources */,
0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */,
D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */,

View File

@ -345,9 +345,8 @@ import UIKit
numberOfDigits = model.digits
if let entryType = model.type {
setAsSecureTextEntry(entryType == .secure || entryType == .password)
}
let entryType = model.type
setAsSecureTextEntry(entryType == .secure || entryType == .password)
let observingDelegate = delegateObject?.observingTextFieldDelegate ?? self

View File

@ -0,0 +1,347 @@
//
// InputEntryField.swift
// MVMCoreUI
//
// Created by Matt Bruce on 7/16/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
@objcMembers open class InputEntryField: VDS.InputField, VDSMoleculeViewProtocol, ObservingTextFieldDelegate, ViewMaskingProtocol {
//------------------------------------------------------
// MARK: - Properties
//------------------------------------------------------
open var viewModel: TextEntryFieldModel!
open var delegateObject: MVMCoreUIDelegateObject?
open var additionalData: [AnyHashable : Any]?
// Form Validation
var fieldKey: String?
var fieldValue: JSONValue?
var groupName: String?
//--------------------------------------------------
// MARK: - Stored Properties
//--------------------------------------------------
public var isValid: Bool = true
/// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well.
private weak var proprietorTextDelegate: UITextFieldDelegate?
private var isEditting: Bool = false {
didSet {
viewModel.selected = isEditting
}
}
//--------------------------------------------------
// MARK: - Stored Properties
//--------------------------------------------------
private var observingForChange: Bool = false
/// Validate when user resigns editing. Default: true
open var validateWhenDoneEditing: Bool = true
open var shouldMaskWhileRecording: Bool {
return viewModel.shouldMaskRecordedView ?? false
}
//--------------------------------------------------
// MARK: - Computed Properties
//--------------------------------------------------
/// The text of this TextField.
open override var text: String? {
didSet {
viewModel?.text = text
}
}
open override var errorText: String? {
get {
viewModel.dynamicErrorMessage ?? viewModel.errorMessage
}
set {}
}
/// Placeholder access for the TextField.
public var placeholder: String? {
get { textField.placeholder }
set { textField.placeholder = newValue }
}
//--------------------------------------------------
// MARK: - Delegate Properties
//--------------------------------------------------
/// The delegate and block for validation. Validates if the text that the user has entered.
public weak var observingTextFieldDelegate: ObservingTextFieldDelegate?
/// If you're using a ViewController, you must set this to it
open weak var uiTextFieldDelegate: UITextFieldDelegate?
{
get { textField.delegate }
set {
textField.delegate = self
proprietorTextDelegate = newValue
}
}
//--------------------------------------------------
// MARK: - Lifecycle
//--------------------------------------------------
open override func setup() {
super.setup()
//turn off internal required rule
useRequiredRule = false
publisher(for: .valueChanged)
.sink { [weak self] control in
guard let self else { return }
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
if (viewModel.type == .email) {
// remove spaces (either user entered Or auto-correct suggestion) for the email field
text = textField.text?.replacingOccurrences(of: " ", with: "")
}
}.store(in: &subscribers)
textField
.publisher(for: .editingDidBegin)
.sink { [weak self] textView in
guard let self else { return }
isEditting = true
if viewModel.clearTextOnTap {
text = ""
}
}.store(in: &subscribers)
textField
.publisher(for: .editingDidEnd)
.sink { [weak self] textView in
guard let self else { return }
isEditting = false
if validateWhenDoneEditing, let valid = viewModel.isValid {
updateValidation(valid)
}
regexTextFieldOutputIfAvailable()
}.store(in: &subscribers)
}
open override func updateView() {
super.updateView()
if let viewModel {
switch viewModel.type {
case .secure:
textField.isSecureTextEntry = true
textField.shouldMaskWhileRecording = true
case .numberSecure:
textField.isSecureTextEntry = true
textField.shouldMaskWhileRecording = true
textField.keyboardType = .numberPad
case .email:
textField.keyboardType = .emailAddress
case .securityCode, .creditCard, .password:
textField.shouldMaskWhileRecording = true
default:
break;
}
// Override the preset keyboard set in type.
if let keyboardType = viewModel.assignKeyboardType() {
textField.keyboardType = keyboardType
}
}
}
open func viewModelDidUpdate() {
fieldType = viewModel.type.toVDSFieldType()
text = viewModel.text
placeholder = viewModel.placeholder
labelText = viewModel.title
helperText = viewModel.feedback
isEnabled = viewModel.enabled
isReadOnly = viewModel.readOnly
isRequired = viewModel.required
tooltipModel = viewModel.tooltip?.toVDSTooltipModel()
width = viewModel.width
transparentBackground = viewModel.transparentBackground
containerView.accessibilityIdentifier = model.accessibilityIdentifier
textField.textAlignment = viewModel.textAlignment
textField.enableClipboardActions = viewModel.enableClipboardActions
textField.placeholder = viewModel.placeholder ?? ""
uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate
observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate
if (viewModel.selected ?? false) && !viewModel.wasInitiallySelected {
viewModel.wasInitiallySelected = true
isEditting = true
}
viewModel.rules = rules
FormValidator.setupValidation(for: viewModel, delegate: delegateObject?.formHolderDelegate)
if isEditting {
DispatchQueue.main.async {
_ = self.becomeFirstResponder()
}
}
viewModel.updateUI = {
MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in
guard let self = self else { return }
if isEditting {
updateValidation(viewModel.isValid ?? true)
} else if viewModel.isValid ?? true && showError {
showError = false
}
isEnabled = viewModel.enabled
})
}
viewModel.updateUIDynamicError = {
MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in
guard let self = self else { return }
let validState = viewModel.isValid ?? false
if !validState && viewModel.shouldClearText {
text = ""
viewModel.shouldClearText = false
}
updateValidation(validState)
})
}
//Added to override text when view is reloaded.
if let text = viewModel.text, !text.isEmpty {
regexTextFieldOutputIfAvailable()
}
}
//--------------------------------------------------
// MARK: - Observing for Change (TextFieldDelegate)
//--------------------------------------------------
@objc public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
observingTextFieldDelegate = delegate
uiTextFieldDelegate = delegate
}
func regexTextFieldOutputIfAvailable() {
if let regex = viewModel?.displayFormat,
let mask = viewModel?.displayMask,
let finalText = text {
let range = NSRange(finalText.startIndex..., in: finalText)
if let regex = try? NSRegularExpression(pattern: regex) {
let maskedText = regex.stringByReplacingMatches(in: finalText,
range: range,
withTemplate: mask)
textField.text = maskedText
}
}
}
@objc public func dismissFieldInput(_ sender: Any?) {
_ = resignFirstResponder()
}
private func updateValidation(_ isValid: Bool) {
let previousValidity = self.isValid
self.isValid = isValid
if previousValidity && !isValid {
showError = true
observingTextFieldDelegate?.isValid?(textfield: self)
} else if (!previousValidity && isValid) {
showError = false
observingTextFieldDelegate?.isInvalid?(textfield: self)
}
}
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
//--------------------------------------------------
@objc open func updateView(_ size: CGFloat) {}
}
extension InputEntryField {
//--------------------------------------------------
// MARK: - Implemented TextField Delegate
//--------------------------------------------------
@discardableResult
@objc public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
proprietorTextDelegate?.textFieldShouldReturn?(textField) ?? true
}
@objc public override func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
proprietorTextDelegate?.textField?(textField, shouldChangeCharactersIn: range, replacementString: string)
??
super.textField(textField, shouldChangeCharactersIn: range, replacementString: string)
}
@objc public override func textFieldDidBeginEditing(_ textField: UITextField) {
proprietorTextDelegate?.textFieldDidBeginEditing?(textField) ?? super.textFieldDidBeginEditing(textField)
}
@objc public override func textFieldDidEndEditing(_ textField: UITextField) {
proprietorTextDelegate?.textFieldDidEndEditing?(textField) ?? super.textFieldDidEndEditing(textField)
}
@objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
proprietorTextDelegate?.textFieldShouldBeginEditing?(textField) ?? true
}
@objc public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
proprietorTextDelegate?.textFieldShouldEndEditing?(textField) ?? true
}
@objc public func textFieldShouldClear(_ textField: UITextField) -> Bool {
proprietorTextDelegate?.textFieldShouldClear?(textField) ?? true
}
}
// MARK: - Accessibility
extension InputEntryField {
@objc open func pushAccessibilityNotification() {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
UIAccessibility.post(notification: .layoutChanged, argument: containerView)
}
}
}
internal struct ViewMasking {
static var shouldMaskWhileRecording: UInt8 = 0
}
extension VDS.TextField: ViewMaskingProtocol {
public var shouldMaskWhileRecording: Bool {
get {
return (objc_getAssociatedObject(self, &ViewMasking.shouldMaskWhileRecording) as? Bool) ?? false
}
set {
objc_setAssociatedObject(self, &ViewMasking.shouldMaskWhileRecording, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}

View File

@ -14,7 +14,7 @@ import MVMCore
/**
This class provides the convenience of formatting the MDN entered/displayer for the user.
*/
@objcMembers open class MdnEntryField: TextEntryField, ABPeoplePickerNavigationControllerDelegate, CNContactPickerDelegate {
@objcMembers open class MdnEntryField: InputEntryField, ABPeoplePickerNavigationControllerDelegate, CNContactPickerDelegate {
//--------------------------------------------------
// MARK: - Stored Properties
//--------------------------------------------------
@ -47,52 +47,17 @@ import MVMCore
get { MVMCoreUIUtility.removeMdnFormat(text) }
set { text = MVMCoreUIUtility.formatMdn(newValue) }
}
/// Toggles selected or original (unselected) UI.
public override var isSelected: Bool {
get { return entryFieldContainer.isSelected }
set (selected) {
if selected && showError {
showError = false
}
super.isSelected = selected
}
}
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
@objc public override init(frame: CGRect) {
super.init(frame: .zero)
}
@objc public convenience init() {
self.init(frame: .zero)
}
@objc required public init?(coder: NSCoder) {
super.init(coder: coder)
fatalError("MdnEntryField xib not supported.")
}
required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.init(model: model, delegateObject, additionalData)
}
//--------------------------------------------------
// MARK: - Setup
//--------------------------------------------------
@objc public override func setupFieldContainerContent(_ container: UIView) {
super.setupFieldContainerContent(container)
textField.keyboardType = .numberPad
open override func setup() {
super.setup()
setupTextFieldToolbar()
}
open override func setupTextFieldToolbar() {
open func setupTextFieldToolbar() {
let toolbar = UIToolbar.createEmptyToolbar()
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let contacts = UIBarButtonItem(title: MVMCoreUIUtility.hardcodedString(withKey: "textfield_contacts_barbutton"), style: .plain, target: self, action: #selector(getContacts))
@ -103,40 +68,7 @@ import MVMCore
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
@objc public func hasValidMDN() -> Bool {
guard let MDN = mdn, !MDN.isEmpty else { return false }
if isNationalMDN {
return MVMCoreUIUtility.validateMDNString(MDN)
}
return MVMCoreUIUtility.validateInternationalMDNString(MDN)
}
@objc public func validateMDNTextField() -> Bool {
guard !shouldValidateMDN, let MDN = mdn, !MDN.isEmpty else {
isValid = true
return true
}
isValid = hasValidMDN()
if self.isValid {
showError = false
} else {
entryFieldModel?.errorMessage = entryFieldModel?.errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
showError = true
UIAccessibility.post(notification: .layoutChanged, argument: textField)
}
return isValid
}
//--------------------------------------------------
@objc public func getContacts(_ sender: Any?) {
let picker = CNContactPickerViewController()
@ -152,11 +84,12 @@ import MVMCore
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
//--------------------------------------------------
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
textField.keyboardType = .phonePad
public override func viewModelDidUpdate() {
viewModel.type = .phone
super.viewModelDidUpdate()
if let phoneNumber = viewModel.text {
text = phoneNumber.formatUSNumber()
}
}
//--------------------------------------------------
@ -179,62 +112,47 @@ import MVMCore
let startIndex = unformedMDN.index(unformedMDN.startIndex, offsetBy: 1)
unformattedMDN = String(unformedMDN[startIndex...])
}
text = unformattedMDN
textFieldShouldReturn(textField)
textFieldDidEndEditing(textField)
}
}
//--------------------------------------------------
// MARK: - Implemented TextField Delegate
//--------------------------------------------------
@discardableResult
@objc public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return proprietorTextDelegate?.textFieldShouldReturn?(textField) ?? true
@objc public override func textFieldShouldReturn(_ textField: UITextField) -> Bool {
_ = resignFirstResponder()
let superValue = super.textFieldShouldReturn(textField)
return proprietorTextDelegate?.textFieldShouldReturn?(textField) ?? superValue
}
@objc public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if !MVMCoreUIUtility.validate(string, withRegularExpression: RegularExpressionDigitOnly) {
return false
}
return proprietorTextDelegate?.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) ?? true
@objc public override func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let superValue = super.textField(textField, shouldChangeCharactersIn: range, replacementString: string)
return proprietorTextDelegate?.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) ?? superValue
}
@objc public func textFieldDidBeginEditing(_ textField: UITextField) {
textField.text = MVMCoreUIUtility.removeMdnFormat(textField.text)
@objc public override func textFieldDidBeginEditing(_ textField: UITextField) {
super.textFieldDidBeginEditing(textField)
proprietorTextDelegate?.textFieldDidBeginEditing?(textField)
}
@objc public func textFieldDidEndEditing(_ textField: UITextField) {
@objc public override func textFieldDidEndEditing(_ textField: UITextField) {
proprietorTextDelegate?.textFieldDidEndEditing?(textField)
if validateMDNTextField() {
if isNationalMDN {
textField.text = MVMCoreUIUtility.formatMdn(textField.text)
}
// Validate the base input field along with triggering form field validation rules.
validateText()
}
super.textFieldDidEndEditing(textField)
}
@objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
@objc public override func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
proprietorTextDelegate?.textFieldShouldBeginEditing?(textField) ?? true
}
@objc public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
@objc public override func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
proprietorTextDelegate?.textFieldShouldEndEditing?(textField) ?? true
}
@objc public func textFieldShouldClear(_ textField: UITextField) -> Bool {
@objc public override func textFieldShouldClear(_ textField: UITextField) -> Bool {
proprietorTextDelegate?.textFieldShouldClear?(textField) ?? true
}
}

View File

@ -12,4 +12,9 @@
//--------------------------------------------------
public override class var identifier: String { "mdnEntryField" }
open override func formFieldServerValue() -> AnyHashable? {
guard let value = formFieldValue() as? String else { return nil }
return value.filter { $0.isNumber }
}
}

View File

@ -11,9 +11,9 @@ import UIKit
@objc public protocol ObservingTextFieldDelegate {
/// Called when the entered text becomes valid based on the validation block
@objc optional func isValid(textfield: TextEntryField?)
@objc optional func isValid(textfield: Any?)
/// Called when the entered text becomes invalid based on the validation block
@objc optional func isInvalid(textfield: TextEntryField?)
@objc optional func isInvalid(textfield: Any?)
/// Dismisses the keyboard.
@objc optional func dismissFieldInput(_ sender: Any?)
}
@ -317,9 +317,9 @@ import UIKit
super.shouldShowError(showError)
if showError {
observingTextFieldDelegate?.isValid?(textfield: self)
} else {
observingTextFieldDelegate?.isInvalid?(textfield: self)
} else {
observingTextFieldDelegate?.isValid?(textfield: self)
}
}

View File

@ -5,9 +5,10 @@
// Created by Kevin Christiano on 1/22/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import VDS
@objcMembers open class TextEntryFieldModel: EntryFieldModel {
@objcMembers open class TextEntryFieldModel: EntryFieldModel, FormFieldInternalValidatableProtocol {
//--------------------------------------------------
// MARK: - Types
//--------------------------------------------------
@ -20,6 +21,39 @@
case email
case text
case phone
//additional
case inlineAction
case creditCard
case date
case securityCode
public func toVDSFieldType() -> VDS.InputField.FieldType {
switch self {
case .password:
.password
case .secure:
.text
case .number:
.number
case .numberSecure:
.number
case .email:
.text
case .text:
.text
case .phone:
.telephone
case .inlineAction:
.inlineAction
case .creditCard:
.creditCard
case .date:
.date
case .securityCode:
.securityCode
}
}
}
//--------------------------------------------------
@ -33,12 +67,21 @@
public var disabledTextColor: Color = Color(uiColor: .mvmCoolGray3)
public var textAlignment: NSTextAlignment = .left
public var keyboardOverride: String?
public var type: EntryType?
public var type: EntryType = .text
public var clearTextOnTap: Bool = false
public var displayFormat: String?
public var displayMask: String?
public var enableClipboardActions: Bool = true
public var tooltip: TooltipModel?
public var transparentBackground: Bool = false
public var width: CGFloat?
//--------------------------------------------------
// MARK: - FormFieldInternalValidatableProtocol
//--------------------------------------------------
open var rules: [AnyRule<String>]?
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
@ -114,6 +157,9 @@
case displayFormat
case displayMask
case enableClipboardActions
case tooltip
case transparentBackground
case width
}
//--------------------------------------------------
@ -128,7 +174,7 @@
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)
type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type) ?? .text
if let clearTextOnTap = try typeContainer.decodeIfPresent(Bool.self, forKey: .clearTextOnTap) {
self.clearTextOnTap = clearTextOnTap
@ -149,6 +195,10 @@
if let enableClipboardActions = try typeContainer.decodeIfPresent(Bool.self, forKey: .enableClipboardActions) {
self.enableClipboardActions = enableClipboardActions
}
tooltip = try typeContainer.decodeIfPresent(TooltipModel.self, forKey: .tooltip)
transparentBackground = try typeContainer.decodeIfPresent(Bool.self, forKey: .transparentBackground) ?? false
width = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .width)
}
open override func encode(to encoder: Encoder) throws {
@ -164,5 +214,8 @@
try container.encode(disabledTextColor, forKey: .disabledTextColor)
try container.encode(clearTextOnTap, forKey: .clearTextOnTap)
try container.encode(enableClipboardActions, forKey: .enableClipboardActions)
try container.encodeIfPresent(tooltip, forKey: .tooltip)
try container.encode(transparentBackground, forKey: .transparentBackground)
try container.encodeIfPresent(width, forKey: .width)
}
}

View File

@ -41,7 +41,7 @@ open class CoreUIModelMapping: ModelMapping {
ModelRegistry.register(handler: ButtonGroup.self, for: ButtonGroupModel.self)
// MARK:- Entry Field
ModelRegistry.register(handler: TextEntryField.self, for: TextEntryFieldModel.self)
ModelRegistry.register(handler: InputEntryField.self, for: TextEntryFieldModel.self)
ModelRegistry.register(handler: MdnEntryField.self, for: MdnEntryFieldModel.self)
ModelRegistry.register(handler: DigitEntryField.self, for: DigitEntryFieldModel.self)
ModelRegistry.register(handler: ItemDropdownEntryField.self, for: ItemDropdownEntryFieldModel.self)