latest state of updates
This commit is contained in:
parent
bcb296fa5d
commit
98e4f3d621
@ -32,9 +32,7 @@ import UIKit
|
||||
}()
|
||||
|
||||
public var dateFormat: String = "MMM d, y" {
|
||||
didSet {
|
||||
dateFormatter.dateFormat = dateFormat
|
||||
}
|
||||
didSet { dateFormatter.dateFormat = dateFormat }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -33,7 +33,10 @@
|
||||
required public init(from decoder: Decoder) throws {
|
||||
try super.init(from: decoder)
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
dateFormat = try typeContainer.decodeIfPresent(String.self, forKey: .dateFormat) ?? "MMM d, y"
|
||||
|
||||
if let dateFormat = try typeContainer.decodeIfPresent(String.self, forKey: .dateFormat) {
|
||||
self.dateFormat = dateFormat
|
||||
}
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
|
||||
@ -246,15 +246,6 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
@objc public override func defaultValidationBlock() {
|
||||
|
||||
validationBlock = { enteredValue in
|
||||
guard let enteredValue = enteredValue else { return false }
|
||||
|
||||
return enteredValue.count > 0 && enteredValue.count == self.digitBoxes.count
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func selectPreviousDigitField(_ currentTextField: UITextField?, clear: Bool) {
|
||||
|
||||
var selectPreviousField = false
|
||||
|
||||
@ -36,8 +36,14 @@
|
||||
required public init(from decoder: Decoder) throws {
|
||||
try super.init(from: decoder)
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
digits = try typeContainer.decodeIfPresent(Int.self, forKey: .digits) ?? 4
|
||||
secureEntry = try typeContainer.decodeIfPresent(Bool.self, forKey: .secureEntry) ?? false
|
||||
|
||||
if let digits = try typeContainer.decodeIfPresent(Int.self, forKey: .digits) {
|
||||
self.digits = digits
|
||||
}
|
||||
|
||||
if let secureEntry = try typeContainer.decodeIfPresent(Bool.self, forKey: .secureEntry) {
|
||||
self.secureEntry = secureEntry
|
||||
}
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
|
||||
@ -20,7 +20,7 @@ import UIKit
|
||||
|
||||
public private(set) var titleLabel: Label = {
|
||||
let label = Label()
|
||||
label.font = MFStyler.fontRegularMicro()
|
||||
label.font = Styler.Font.RegularMicro.getFont()
|
||||
label.textColor = .mvmBlack
|
||||
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
return label
|
||||
@ -31,7 +31,7 @@ import UIKit
|
||||
/// Provides contextual information on the TextField.
|
||||
public private(set) var feedbackLabel: Label = {
|
||||
let label = Label()
|
||||
label.font = MFStyler.fontRegularMicro()
|
||||
label.font = Styler.Font.RegularMicro.getFont()
|
||||
label.textColor = .mvmBlack
|
||||
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
return label
|
||||
@ -174,8 +174,6 @@ import UIKit
|
||||
@objc final public override func setupView() {
|
||||
super.setupView()
|
||||
|
||||
guard subviews.isEmpty else { return }
|
||||
|
||||
isAccessibilityElement = false
|
||||
setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
accessibilityElements = [titleLabel, feedbackLabel]
|
||||
@ -258,13 +256,13 @@ import UIKit
|
||||
title = model.title
|
||||
feedback = model.feedback
|
||||
errorMessage = model.errorMessage
|
||||
isEnabled = model.isEnabled
|
||||
isEnabled = model.enabled
|
||||
|
||||
if let isLocked = model.isLocked {
|
||||
if let isLocked = model.locked {
|
||||
self.isLocked = isLocked
|
||||
|
||||
} else if let isSelected = model.isSelected{
|
||||
self.isSelected = isSelected
|
||||
} else if let selected = model.selected {
|
||||
self.isSelected = selected
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
import Foundation
|
||||
|
||||
|
||||
@objcMembers public class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol {
|
||||
|
||||
@objcMembers public class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, EnableableModelProtocol {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
@ -20,31 +20,24 @@ import Foundation
|
||||
}
|
||||
|
||||
public var backgroundColor: Color?
|
||||
public var title: String?
|
||||
public var title: String = ""
|
||||
public var feedback: String?
|
||||
public var errorMessage: String = ""
|
||||
public var isEnabled: Bool = true
|
||||
public var isLocked: Bool?
|
||||
public var isSelected: Bool?
|
||||
public var enabled: Bool = true
|
||||
public var locked: Bool?
|
||||
public var selected: Bool?
|
||||
public var text: String?
|
||||
|
||||
public var fieldKey: String?
|
||||
public var groupName: String = FormValidator.defaultGroupName
|
||||
public var baseValue: AnyHashable?
|
||||
|
||||
|
||||
public var isValid: Bool? {
|
||||
didSet {
|
||||
updateUI?()
|
||||
}
|
||||
didSet { updateUI?() }
|
||||
}
|
||||
|
||||
/// Temporary binding mechanism for the view to update on enable changes.
|
||||
public var updateUI: (() -> Void)?
|
||||
public var updateUI: (() -> ())?
|
||||
|
||||
public func setValidity(_ valid: Bool, rule: RulesProtocol) {
|
||||
self.isValid = valid
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
@ -52,23 +45,29 @@ import Foundation
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case title = "label"
|
||||
case isEnabled
|
||||
case title
|
||||
case enabled
|
||||
case feedback
|
||||
case errorMessage = "errorMsg"
|
||||
case isLocked
|
||||
case isSelected
|
||||
case isValid
|
||||
case isRequired = "required"
|
||||
case errorMessage
|
||||
case locked
|
||||
case selected
|
||||
case text
|
||||
case fieldKey
|
||||
case groupName
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Validation Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
public func formFieldValue() -> AnyHashable? {
|
||||
return text
|
||||
}
|
||||
|
||||
public func setValidity(_ valid: Bool, rule: RulesProtocol) {
|
||||
self.isValid = valid
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
@ -81,20 +80,26 @@ import Foundation
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
|
||||
feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback)
|
||||
errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage) ?? ""
|
||||
isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEnabled) ?? true
|
||||
isLocked = try typeContainer.decodeIfPresent(Bool.self, forKey: .isLocked)
|
||||
isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .isSelected)
|
||||
isValid = try typeContainer.decodeIfPresent(Bool.self, forKey: .isValid)
|
||||
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
||||
|
||||
if let title = try typeContainer.decodeIfPresent(String.self, forKey: .title) {
|
||||
self.title = title
|
||||
}
|
||||
|
||||
feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback)
|
||||
|
||||
if let errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage) {
|
||||
self.errorMessage = errorMessage
|
||||
}
|
||||
|
||||
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
||||
self.enabled = enabled
|
||||
}
|
||||
|
||||
locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked)
|
||||
selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected)
|
||||
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
||||
baseValue = text
|
||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||
self.groupName = groupName
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@ -103,13 +108,11 @@ import Foundation
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(title, forKey: .title)
|
||||
try container.encodeIfPresent(feedback, forKey: .feedback)
|
||||
try container.encode(errorMessage, forKey: .errorMessage)
|
||||
try container.encode(isEnabled, forKey: .isEnabled)
|
||||
try container.encode(isLocked, forKey: .isLocked)
|
||||
try container.encode(isSelected, forKey: .isSelected)
|
||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||
try container.encodeIfPresent(isValid, forKey: .isValid)
|
||||
try container.encodeIfPresent(text, forKey: .text)
|
||||
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||
try container.encodeIfPresent(locked, forKey: .locked)
|
||||
try container.encodeIfPresent(selected, forKey: .selected)
|
||||
try container.encode(errorMessage, forKey: .errorMessage)
|
||||
try container.encode(enabled, forKey: .enabled)
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,8 +35,14 @@
|
||||
required public init(from decoder: Decoder) throws {
|
||||
try super.init(from: decoder)
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
options = try typeContainer.decode([String].self, forKey: .options)
|
||||
selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) ?? 0
|
||||
|
||||
if let options = try typeContainer.decodeIfPresent([String].self, forKey: .options) {
|
||||
self.options = options
|
||||
}
|
||||
|
||||
if let selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) {
|
||||
self.selectedIndex = selectedIndex
|
||||
}
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
|
||||
@ -107,18 +107,18 @@ import MVMCore
|
||||
isValid = true
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
let isValid = hasValidMDN()
|
||||
|
||||
|
||||
if isValid {
|
||||
showError = false
|
||||
|
||||
|
||||
} else {
|
||||
errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
|
||||
showError = true
|
||||
UIAccessibility.post(notification: .layoutChanged, argument: textField)
|
||||
}
|
||||
|
||||
|
||||
return isValid
|
||||
}
|
||||
|
||||
@ -196,7 +196,7 @@ import MVMCore
|
||||
}
|
||||
|
||||
@objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
|
||||
|
||||
|
||||
return proprietorTextDelegate?.textFieldShouldBeginEditing?(textField) ?? true
|
||||
}
|
||||
|
||||
|
||||
@ -37,9 +37,7 @@ import UIKit
|
||||
}()
|
||||
|
||||
public var accessoryView: View? {
|
||||
didSet {
|
||||
accessoryView == nil ? removeAccessoryView() : constrainAccessoryView()
|
||||
}
|
||||
didSet { accessoryView == nil ? removeAccessoryView() : constrainAccessoryView() }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -108,12 +106,6 @@ import UIKit
|
||||
set { textField.placeholder = newValue }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Property Observers
|
||||
//--------------------------------------------------
|
||||
|
||||
public var validationBlock: ((_ value: String?) -> Bool)?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Delegate Properties
|
||||
//--------------------------------------------------
|
||||
@ -155,9 +147,11 @@ import UIKit
|
||||
textFieldTrailingConstraint = accessoryView?.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two)
|
||||
textFieldTrailingConstraint?.isActive = true
|
||||
|
||||
accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: accessoryView!.trailingAnchor, constant: Padding.Four)
|
||||
accessoryViewTrailingConstraint?.isActive = true
|
||||
accessoryView?.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true
|
||||
if let accessoryView = accessoryView {
|
||||
accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: accessoryView.trailingAnchor, constant: Padding.Four)
|
||||
accessoryViewTrailingConstraint?.isActive = true
|
||||
accessoryView.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true
|
||||
}
|
||||
}
|
||||
|
||||
public func removeAccessoryView() {
|
||||
@ -242,15 +236,7 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
// MARK: - Observing for Change (TextFieldDelegate)
|
||||
//--------------------------------------------------
|
||||
|
||||
public func defaultValidationBlock() {
|
||||
|
||||
validationBlock = { enteredValue in
|
||||
guard let enteredValue = enteredValue else { return false }
|
||||
return enteredValue.count > 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@discardableResult
|
||||
@objc override open func resignFirstResponder() -> Bool {
|
||||
if validateWhenDoneEditing {
|
||||
@ -317,11 +303,14 @@ import UIKit
|
||||
|
||||
model.updateUI = { [weak self] in
|
||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||
if self?.isSelected ?? false {
|
||||
self?.updateValidation(model.isValid ?? true)
|
||||
guard let self = self else { return }
|
||||
|
||||
if self.isSelected {
|
||||
self.updateValidation(model.isValid ?? true)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
self.delegateObject = delegateObject
|
||||
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
|
||||
textColor.enabled = model.enabledTextColor?.uiColor
|
||||
@ -343,15 +332,6 @@ import UIKit
|
||||
break
|
||||
}
|
||||
|
||||
if let regex = model.regex, !regex.isEmpty {
|
||||
validationBlock = { enteredValue in
|
||||
guard let value = enteredValue else { return false }
|
||||
return MVMCoreUIUtility.validate(value, withRegularExpression: regex)
|
||||
}
|
||||
} else {
|
||||
defaultValidationBlock()
|
||||
}
|
||||
|
||||
uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate
|
||||
observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate
|
||||
textField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: observingTextFieldDelegate ?? self)
|
||||
|
||||
@ -8,6 +8,9 @@
|
||||
|
||||
|
||||
@objcMembers public class TextEntryFieldModel: EntryFieldModel {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Types
|
||||
//--------------------------------------------------
|
||||
|
||||
public enum EntryType: String, Codable {
|
||||
case password
|
||||
@ -27,7 +30,6 @@
|
||||
public var enabledTextColor: Color?
|
||||
public var disabledTextColor: Color?
|
||||
public var type: EntryType?
|
||||
public var regex: String?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
@ -40,7 +42,6 @@
|
||||
case enabledTextColor
|
||||
case disabledTextColor
|
||||
case type
|
||||
case regex
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -55,7 +56,6 @@
|
||||
enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor)
|
||||
disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor)
|
||||
type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type)
|
||||
regex = try typeContainer.decodeIfPresent(String.self, forKey: .regex)
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
@ -67,6 +67,5 @@
|
||||
try container.encodeIfPresent(enabledTextColor, forKey: .enabledTextColor)
|
||||
try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor)
|
||||
try container.encodeIfPresent(type, forKey: .type)
|
||||
try container.encodeIfPresent(regex, forKey: .regex)
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,9 +25,7 @@ import UIKit
|
||||
|
||||
/// Total control over the drawn top, bottom, left and right borders.
|
||||
public var disableAllBorders = false {
|
||||
didSet {
|
||||
bottomBar?.isHidden = disableAllBorders
|
||||
}
|
||||
didSet { bottomBar?.isHidden = disableAllBorders }
|
||||
}
|
||||
|
||||
private(set) var fieldState: FieldState = .original {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user